尽管使用XmlNamespaceManager,XPATH SelectSingleNode仍返回null

时间:2014-10-21 14:35:22

标签: c# xml xpath

我正在尝试测试这样的XML文档(在本例中为SAML):

<saml2p:LogoutRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="_bbcf6cc5-8832-4567-9a52-7baef04676d7" Version="2.0" IssueInstant="2014-10-21T13:24:54.1397367Z" NotOnOrAfter="2014-10-21T13:34:54.1397367Z">
    <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo>
            <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
            <Reference URI="#_bbcf6cc5-8832-4567-9a52-7baef04676d7">
                <Transforms>
                    <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                    <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                </Transforms>
                <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                <DigestValue>DigestValueGoesHere!</DigestValue>
            </Reference>
        </SignedInfo>
        <SignatureValue>SignatureValueGoesHere!
        </SignatureValue>
        <KeyInfo>
            <X509Data>
              <X509Certificate>X509CertificateGoesHere!</X509Certificate>
            </X509Data>
        </KeyInfo>
    </Signature>
</saml2p:LogoutRequest>

为此目的,我已经创建了一些我试图用来测试XML的扩展:

public static class XmlExtensions
    {
        public static XmlNode Signature(this XmlDocument document)
        {
            return document.SelectSingleNodeFromDocumentRoot(@"/saml2p:LogoutRequest/Signature");
        }

        private static XmlNode SelectSingleNodeFromDocumentRoot(this XmlDocument document, string path)
        {
            var ns = new XmlNamespaceManager(document.NameTable);

            ns.AddNamespace("saml2", @"urn:oasis:names:tc:SAML:2.0:assertion");
            ns.AddNamespace("saml2p", @"urn:oasis:names:tc:SAML:2.0:protocol");
            ns.AddNamespace("ns1", @"http://www.w3.org/2000/09/xmldsig#");

            var result = document.SelectSingleNode(path, ns);
            return result;
        }
    }

在我的一个测试中,我正在尝试检索/saml2p:LogoutRequest/Signature元素,但是我的扩展名返回null。为什么?我以为我应该使用添加了xml命名空间的提供的ns管理器?请注意,查询路径在XPath Visualizer Tool中完美无缺。

1 个答案:

答案 0 :(得分:3)

Signature位于命名空间xmlns="http://www.w3.org/2000/09/xmldsig#"中,因此您需要调整:

return document.SelectSingleNodeFromDocumentRoot(@"/saml2p:LogoutRequest/ns1:Signature");