Нулевой возврат по 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); возвращает ноль, когда я ожидал, что он вернет элемент сообщения.
Я очень подозреваю, что это связано с пустым пространством имен, которое я настроил, но я не могу найти правильную комбинацию значений, чтобы заставить его работать.
Любые указатели будут оценены.
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);
Это работает
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>