如何使用没有关联前缀的命名空间在C#中读取XML文档

时间:2011-10-25 05:04:44

标签: c# .net xml xml-parsing

我正在尝试阅读OSIS格式的文档。我已将文档剪切成一个简单的片段:

<?xml version="1.0" encoding="utf-8"?>
<osis xmlns="http://www.bibletechnologies.net/2003/OSIS/namespace">
  <osisText osisRefWork="Bible" osisIDWork="kjv" xml:lang="en">
  </osisText>
</osis>

我尝试使用MSDN文档中的示例代码阅读它:

XPathDocument document = new XPathDocument("osis.xml");
XPathNavigator navigator = document.CreateNavigator();
XPathNodeIterator nodes = navigator.Select("/osis/osisText");

while (nodes.MoveNext())
{
    Console.WriteLine(nodes.Current.Name);
}

问题是选择不包含任何节点并且不会引发异常。由于代码丢弃了根标记,我无法读取文档。如果我从root osis标签中删除xmlns =“http://www.bibletechnologies.net/2003/OSIS/namespace”,它就可以正常工作。攻击性URL返回404代码,但我发现此XML没有任何问题。有人可以解释为什么这段代码不会读取文件?除了在尝试加载每个文档之前手动编辑每个文档之外,我还有哪些选项?

2 个答案:

答案 0 :(得分:9)

您的XPath表达式缺少名称空间前缀。

您尝试选择的元素的名称空间URI为http://www.bibletechnologies.net/2003/OSIS/namespace,而XPath 将使用具有空名称空间URI的路径这些节点。

我在.NET 2.0中测试了这个版本,它找到了预期的节点。

XPathDocument document = new XPathDocument("osis.xml");
XPathNavigator navigator = document.CreateNavigator();

XmlNamespaceManager xmlns = new XmlNamespaceManager(navigator.NameTable);
xmlns.AddNamespace("osis", "http://www.bibletechnologies.net/2003/OSIS/namespace");

XPathNodeIterator nodes = navigator.Select("/osis:osis/osis:osisText", xmlns);

答案 1 :(得分:0)

您可以将文件读取为字符串,替换内存中的命名空间,然后使用字符串流加载它:

string s;
using(var reader = File.OpenText("osis.xml"))
{
    s = reader.ReadToEnd();
}
s = s.Replace("xmlns=\"http://www.bibletechnologies.net/2003/OSIS/namespace\"", "");
Stream stream = new MemoryStream(Encoding.ASCII.GetBytes(s));
XPathDocument document = new XPathDocument("stream");
// Rest of the code