Как читать XML-документ в C # с пространством имен, которое не имеет префикса - PullRequest
3 голосов
/ 25 октября 2011

Я пытаюсь читать документы в формате 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);
}

Проблема состоит в том, что выбор содержитнет узлов и выбрасывает без исключения.Поскольку код отбрасывает корневой тег, я не могу прочитать документ.Если я удаляю xmlns = "http://www.bibletechnologies.net/2003/OSIS/namespace" из корневого тега osis, он работает просто отлично. Оскорбительный URL-адрес возвращает код 404, но в противном случае я не вижу ничего плохого в этом XML. Может кто-нибудь объяснить, почему этот код не будет читатьдокумент? Какие варианты у меня есть, кроме ручного редактирования каждого документа перед попыткой его загрузки?

Ответы [ 2 ]

9 голосов
/ 25 октября 2011

В вашем выражении 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);
0 голосов
/ 25 октября 2011

Вы можете прочитать файл в строку, заменить пространство имен в памяти, а затем загрузить его, используя поток строки:

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
...