Нулево връщане на 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