【问题标题】:Null return on XmlDocument.SelectSingleNode through valid xpath通过有效的 xpath 在 XmlDocument.SelectSingleNode 上返回 Null
【发布时间】:2015-10-11 04:35:04
【问题描述】:

我目前有以下代码

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。

我高度怀疑它与我配置的空白命名空间有关,但我找不到正确的值组合来使其正常工作。

任何指针将不胜感激。

【问题讨论】:

    标签: c# xml default-namespace


    【解决方案1】:

    这是有效的

    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>
    

    【讨论】:

    • 不可能像将 DE 命名空间添加到 xml 一样简单,谢谢
    【解决方案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);
    

    【讨论】:

    • 这也是一个非常好的答案,并且评论很好,当您更多地解释解决方案时,我对此表示赞同,我认为答案更符合发布指南。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多