Нулевой возврат в XmlDocument.SelectSingleNode через допустимый xpath

В настоящее время у меня есть следующий код

nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("soapenv", soapenv_namespace);
nsmgr.AddNamespace("de", de_namespace);

XmlNode xnEnvelope = xmlDoc.SelectSingleNode("//soapenv:Envelope", nsmgr);
XmlNode xnBody = xmlDoc.SelectSingleNode("//soapenv:Envelope/soapenv:Body", nsmgr);
XmlNode xnMessage = xnBody.SelectSingleNode("//soapenv:Envelope/soapenv:Body/message", nsmgr);

Который анализирует следующий xml (усеченный для удобочитаемости)

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
     <soapenv:Body>
        <message     xmlns="http://www.origostandards.com/schema/ce/v2.1/CEBondSingleContractDetailResponse"     xmlns:ns2="http://www.origostandards.com/schema/ce/v2.1/CEBondSingleContractReferenceResponse" xmlns:ns3="http://www.origostandards.com/schema/ce/v2.1/CEBondSingleContractRequest" xmlns:ns4="http://www.origostandards.com/schema/tech/v1.0/SOAPFaultDetail">
        <de:m_content .....

Проблема в строке XmlNode xnMessage = xnBody.SelectSingleNode("//soapenv:Envelope/soapenv:Body/message", nsmgr); возвращает null, когда я ожидаю, что он вернет элемент сообщения.

Я очень подозреваю, что это связано с пустым пространством имен, которое я настроил, но я не могу найти правильную комбинацию значений, чтобы заставить его работать.

Любые указатели будут оценены.


person Ian Jowett    schedule 21.07.2015    source источник


Ответы (2)


Здесь вы ввели пространство имен по умолчанию:

xmlns="http://www.origostandards.com/schema/ce/v2.1/CEBondSingleContractDetailResponse" 

что приводит к тому, что элемент message и все его потомки без префикса распознаются как в этом пространстве имен по умолчанию (если элемент-потомок не имеет локального пространства имен по умолчанию). Чтобы получить доступ к элементу в пространстве имен по умолчанию, просто зарегистрируйте префикс, например d, и сопоставьте его с uri пространства имен по умолчанию:

nsmgr.AddNamespace("d", "http://www.origostandards.com/schema/ce/v2.1/CEBondSingleContractDetailResponse");

Затем используйте вновь зарегистрированный префикс соответственно в выражении XPath:

XmlNode xnBody = xmlDoc.SelectSingleNode("//soapenv:Envelope/soapenv:Body", nsmgr);
XmlNode xnMessage = xnBody.SelectSingleNode("d:message", nsmgr);
person har07    schedule 22.07.2015
comment
Это тоже очень хороший ответ, и он хорошо прокомментирован, я проголосовал за это, поскольку вы больше объясняете решение, и я думаю, что ответ больше соответствует рекомендациям по публикации. - person Ian Jowett; 23.07.2015

Это работает

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(@"C:\Users\DummyUser\Desktop\Noname1.xml");

XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
nsmgr.AddNamespace("de", "http://www.origostandards.com/schema/ce/v2.1/CEBondSingleContractDetailResponse");

XmlNode xnEnvelope = xmlDoc.SelectSingleNode("//soapenv:Envelope", nsmgr);
XmlNode xnBody = xnEnvelope.SelectSingleNode("//soapenv:Body", nsmgr);
XmlNode xnMessage = xnBody.SelectSingleNode("de:message", nsmgr);

а xml файл есть

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
 <soapenv:Body>
    <message xmlns="http://www.origostandards.com/schema/ce/v2.1/CEBondSingleContractDetailResponse"     xmlns:ns2="http://www.origostandards.com/schema/ce/v2.1/CEBondSingleContractReferenceResponse" 
    xmlns:ns3="http://www.origostandards.com/schema/ce/v2.1/CEBondSingleContractRequest" 
    xmlns:ns4="http://www.origostandards.com/schema/tech/v1.0/SOAPFaultDetail">
    This is my sample message
    </message>
</soapenv:Body>
</soapenv:Envelope>
person Thakur    schedule 22.07.2015
comment
Ни в коем случае это не было так просто, как добавить пространство имен DE в xml, спасибо за это - person Ian Jowett; 23.07.2015