从xml文件中获取节点

时间:2012-07-05 16:02:24

标签: c# xml winforms

如何解析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;
        }

3 个答案:

答案 0 :(得分:11)

问题是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实现的)中,当没有提供命名空间时,它总是使用null命名空间,而不是默认命名空间。因此,如果您在XmlNamespaceManager中指定默认命名空间并不重要,那么无论如何它都不会被XPath使用。引用Official XPath Specification

中的相关段落
  

使用。将节点测试中的QName扩展为扩展名   表达式上下文中的名称空间声明。这是一样的   对start和end-tags中的元素类型名称进行扩展   除了不使用xmlns声明的默认命名空间: if   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);

答案 1 :(得分:0)

Sitemap有2个子节点“loc”和“lastmod”。您正在访问的节点是“name”和“url”。这就是为什么你没有得到任何结果。同样在您的XML文件中,最后的sitemap标记没有正确关闭,请使用相应的尝试xn [“loc”]。InnerText并查看是否获得了所需的结果。

答案 2 :(得分:-1)

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

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;
        }