【问题标题】:Can't select descendant nodes despite not having namespaces declared on them尽管没有在其上声明命名空间,但无法选择后代节点
【发布时间】:2015-02-24 15:01:30
【问题描述】:

我正在尝试读取一些 XML:

<?xml version="1.0" encoding="UTF-8"?>
<gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
    <gesmes:subject>Reference rates</gesmes:subject>
    <gesmes:Sender>
        <gesmes:name>European Central Bank</gesmes:name>
    </gesmes:Sender>
    <Cube>
        <Cube time='2015-02-23'>
            <Cube currency='USD' rate='1.1298'/>
            <Cube currency='JPY' rate='134.50'/>
            <Cube currency='BGN' rate='1.9558'/>
            <Cube currency='CZK' rate='27.444'/>
        </Cube>
    </Cube>
</gesmes:Envelope>

我正在使用以下代码解析这些内容:

var path = "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml";
string xml;
using (var wc = new WebClient())
{
    xml = wc.DownloadString(path);
}
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);
XmlNamespaceManager mgr = new XmlNamespaceManager(xmlDoc.NameTable);
mgr.AddNamespace("n", "http://www.gesmes.org/xml/2002-08-01");
1.) XmlNodeList cubes = xmlDoc.SelectNodes("/n:Envelope", mgr); //WORKS
2.) XmlNodeList cubes = xmlDoc.SelectNodes("/n:Envelope/Cube", mgr); //DOES NOT WORK

foreach (XmlNode c in cubes)
{
    // whatever
}

当我打开信封节点 (1.) 时,它可以工作。 但我不知道如何访问命名空间节点(2.)中的子节点。该代码运行,但不返回任何结果。如何访问?

【问题讨论】:

    标签: c# xml xml-namespaces xmldocument


    【解决方案1】:

    信封元素中声明了一个默认命名空间。该元素的任何未声明显式命名空间的后代都将具有默认命名空间。

    XmlNamespaceManager mgr = new XmlNamespaceManager(xmlDoc.NameTable);
    mgr.AddNamespace("n", "http://www.gesmes.org/xml/2002-08-01");
    mgr.AddNamespace("d", "http://www.ecb.int/vocabulary/2002-08-01/eurofxref");
    XmlNodeList cubes = xmlDoc.SelectNodes("/n:Envelope/d:Cube", mgr);
    

    会起作用。请注意添加的名称空间以代替默认名称空间,无论是在管理器中还是在 xpath 中。如果你检查结果,你会发现

    <Cube xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
       <Cube time="2015-02-23">
          <Cube currency="USD" rate="1.1298" />
          <Cube currency="JPY" rate="134.50" />
          <Cube currency="BGN" rate="1.9558" />
          <Cube currency="CZK" rate="27.444" />
       </Cube>
    </Cube>
    

    这清楚地表明有一个默认命名空间属于最外层的 Cube 元素,在这个 xml 片段中,它是根。

    【讨论】:

    • 非常感谢。我已经想出了另一种读取 XML 的方法,但我真的很好奇我在这个简单的源代码上做错了什么。另一方面,我真的很想知道在没有任何管理器的情况下仅使用“xmlDoc.SelectNodes(“/gesmes:Envelope”)”并不是那么简单......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-31
    • 1970-01-01
    • 1970-01-01
    • 2013-01-10
    相关资源
    最近更新 更多