繁体   English   中英

从 xml 文件中获取节点

[英]Get nodes from xml files

如何解析xml文件?

<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> 
<sitemap> 
    <loc>link</loc>
    <lastmod>2011-08-17T08:23:17+00:00</lastmod> 
</sitemap> 
<sitemap>
    <loc>link</loc> 
    <lastmod>2011-08-18T08:23:17+00:00</lastmod> 
</sitemap> 
</sitemapindex>

我是 XML 的新手,我试过这个,但它似乎不起作用:

        XmlDocument xml = new XmlDocument(); //* create an xml document object. 
        xml.Load("sitemap.xml");
        XmlNodeList xnList = xml.SelectNodes("/sitemapindex/sitemap");
        foreach (XmlNode xn in xnList)
        {
            String loc= xn["loc"].InnerText;
            String lastmod= xn["lastmod"].InnerText;
        }

问题在于sitemapindex元素定义了一个默认命名空间。 选择节点时需要指定命名空间,否则将无法找到它们。 例如:

XmlDocument xml = new XmlDocument();
xml.Load("sitemap.xml");
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("s", "http://www.sitemaps.org/schemas/sitemap/0.9");
XmlNodeList xnList = xml.SelectNodes("/s:sitemapindex/s:sitemap", manager);

通常来说,在使用XmlNameSpaceManager ,您可以将前缀保留为空字符串,以指定您希望该命名空间成为默认命名空间。 所以你会认为你可以做这样的事情:

// WON'T WORK
XmlDocument xml = new XmlDocument();
xml.Load("sitemap.xml");
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("", "http://www.sitemaps.org/schemas/sitemap/0.9"); //Empty prefix
XmlNodeList xnList = xml.SelectNodes("/sitemapindex/sitemap", manager); //No prefixes in XPath

但是,如果您尝试该代码,您会发现它找不到任何匹配的节点。 这样做的原因是在 XPath 1.0(这是 XmlDocument 实现的)中,当没有提供命名空间时,它总是使用空命名空间,而不是默认命名空间。 因此,如果您在XmlNamespaceManager指定默认命名空间并不重要,无论如何 XPath 都不会使用它。 引用官方 XPath 规范中的相关段落:

使用表达式上下文中的命名空间声明将节点测试中的 QName 扩展为扩展名称。 这与对开始和结束标签中的元素类型名称进行扩展的方式相同,只是不使用用 xmlns 声明的默认名称空间:如果 QName 没有前缀,则名称空间 URI 为空(这是相同的方式属性名称扩展)。 如果 QName 具有在表达式上下文中没有命名空间声明的前缀,则会出现错误。

因此,当您正在读取的元素属于一个名称空间时,您无法避免将名称空间前缀放在您的 XPath 语句中。 但是,如果您不想费心将命名空间 URI 放在您的代码中,您可以只使用XmlDocument对象来返回根元素的 URI,在这种情况下,这就是您想要的。 例如:

XmlDocument xml = new XmlDocument();
xml.Load("sitemap.xml");
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("s", xml.DocumentElement.NamespaceURI); //Using xml's properties instead of hard-coded URI
XmlNodeList xnList = xml.SelectNodes("/s:sitemapindex/s:sitemap", manager);

站点地图有 2 个子节点“loc”和“lastmod”。 您正在访问的节点是“名称”和“网址”。 这就是为什么你没有得到任何结果。 同样在您的 XML 文件中,最后一个站点地图标记没有正确关闭,请尝试使用 xn["loc"].InnerText 并查看您是否得到所需的结果。

我肯定会使用 LINQ to XML 而不是旧的基于 XmlDocument 的 XML API。 您可以使用以下代码完成您要执行的操作。 请注意,我将要获取其值的元素的名称更改为“loc”和“lastmod”,因为这是您的示例 XML 中的内容(“name”和“url”不存在):

XElement element = XElement.Parse(XMLFILE);
        IEnumerable<XElement> list = element.Elements("sitemap");
        foreach (XElement e in list)
        {
            String LOC= e.Element("loc").Value;
            String LASTMOD = e.Element("lastmod").Value;
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM