尽管没有在其上声明名称空间,但不能 select 个后代节点
Can't select descendant nodes despite not having namespaces declared on them
我正在尝试阅读一些 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.) 中的子节点。该代码运行,但 returns 没有结果。如何访问?
在 Envelope 元素中声明了一个默认命名空间。该元素的任何未声明显式命名空间的后代都将具有默认命名空间。
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>
这清楚地表明有一个默认命名空间属于最外层的多维数据集元素,在这个 xml 片段中,它是根。
我正在尝试阅读一些 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.) 中的子节点。该代码运行,但 returns 没有结果。如何访问?
在 Envelope 元素中声明了一个默认命名空间。该元素的任何未声明显式命名空间的后代都将具有默认命名空间。
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>
这清楚地表明有一个默认命名空间属于最外层的多维数据集元素,在这个 xml 片段中,它是根。