SelectSingleNode и namespace - не удается найти узлы (используя пространство имен mgr) - PullRequest
2 голосов
/ 10 марта 2011

У меня относительно сложное xml-сообщение, полученное от компании-партнера.Мне нужно разобрать XML, чтобы использовать его.У меня все работало нормально, затем они изменили сообщение повсюду, и теперь ни одна из моих команд SelectSingleNode не работает.

Структура сообщения.Обратите внимание на объект CDATA со встроенным XML-документом.Не уверен, что это важно или нет.Мне удалось выкрутить объект dataContent, поэтому он не должен иметь никакого значения.Вот что я загружаю в XmlDocument:

<ns5:dataContent xmlns:ns2="http://test/common/v1" 
                     xmlns="http://test/schema/common" 
                     xmlns:ns4="http://test/credentialing/stuff/v1" 
                     xmlns:ns3="http://test/schema/ims/common/v1" 
                     xmlns:ns5="http://test/schema/v1">

        <createdBy>Micky</createdBy>
        <createdAt>2011-03-08T17:00:27.050-05:00</createdAt>
        <ns5:Id>39</ns5:Id>
        <ns5:Type>4</ns5:Type>
     -- lots more data --
</ns5:dataContent>

мой код довольно прост

   var xmlDoc = new XmlDocument();
   xmlDoc.Load(new StringReader(CDATA content));
   var xmlNsM = new XmlNamespaceManager(xmlData.NameTable);
   xmlNsM.AddNamespace(String.Empty, @"http://test/schema/common\");
   xmlNsM.AddNamespace("ns5", @"http://test/schema/v1\");
   xmlNsM.AddNamespace("m", @"http://test/message/v1\");

//This works
   var order = xmlDoc.ChildNodes[0];

//This returns null
   var ID = order.SelectSingleNode("ns5:Id", xmlNsM);

Я вижу, что xmlDoc загружается правильно.Я попытался добавить все 6 пространств имен в xmlNsM, но получил те же результаты.Ни один из моих SelectSingleNodes сейчас не работает.

В каждом сообщении, которое я нашел на эту тему, говорится, что нужно просто использовать менеджер пространства имен, но я уже знал, что это не очень продуктивный день.

Ответы [ 3 ]

2 голосов
/ 10 марта 2011

Просто читая код, я думаю, вы правильно используете Диспетчер пространства имен. Ваша проблема - запрос XPath. «ns5: Id» не является дочерним элементом документа высокого уровня, и дочерние узлы будут возвращать только один уровень вниз. Вам нужно искать потомков. Попробуйте:

var root = doc.DocumentElement;
var ID = root.SelectSingleNode("//ns5:Id", xmlNsM); 

Это не самый эффективный способ, поскольку он найдет все совпадения во всем документе. Взгляните на некоторые примеры здесь: http://msdn.microsoft.com/en-us/library/ms256086.aspx

1 голос
/ 10 марта 2011

Ну, как это обычно бывает после долгих часов рассмотрения проблемы, решение было простым. Пространства имен, которые я добавил в NSManager, имели косую черту перед закрывающей кавычкой ("http://test/schema/v1\"). Конечно, это разделитель, но, поскольку я только что скопировал и вставил пространство имен из необработанного xml, оно было включено. Как только я удалил я начал искать все необходимые поля в пространстве имен ns5.

Я не вижу элементов, которые по какой-то причине не имеют пространств имен, но, поскольку мне не нужны эти поля ATM, я выясню это позже.

0 голосов
/ 10 марта 2011

@ ErnieL ответ выглядит хорошо (+1).Также может быть проблема с

  xmlNsM.AddNamespace(String.Empty, @"http://test/schema/common\");

, поскольку xpath не любит пространства имен по умолчанию :-(. Если ответ @ErnieL по-прежнему не работает, измените его на

  xmlNsM.AddNamespace("default", @"http://test/schema/common\");
...