c# XPathSelectElement return null 即使指定了命名空间
c# XPathSelectElement return null even if the namespace is specified
我在文件中有这个 xml 文档:
<samlp:AuthnRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_73c4b43a-d201-4990-b656-e6bab19e1c09" Version="2.0" IssueInstant="2021-12-14T08:09:39.816485Z" Destination="https://localhost/idp/sso/post" ForceAuthn="true" AssertionConsumerServiceIndex="0" AssertionConsumerServiceURL="https://localhost:5002/signin-spid" AttributeConsumingServiceIndex="0" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" >
<saml:Issuer NameQualifier="https://localhost:5002" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" >https://localhost:5002</saml:Issuer>
<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/2001/04/xmldsig-more#rsa-sha256" />
<Reference URI="#_73c4b43a-d201-4990-b656-e6bab19e1c09">
<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/2001/04/xmlenc#sha256" />
<DigestValue>.........DigestValue...........</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>..............Signature................</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>...........Certificate.............</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
<samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" />
<saml:Conditions NotBefore="2021-12-14T07:59:39.816485Z" NotOnOrAfter="2021-12-14T08:19:39.816485Z" />
</samlp:AuthnRequest>
我只是想用这段代码获取 SignatureValue 标签值和 X509Certificate 标签值:
var xDocument = XDocument.Load("Request.xml");
var reader = xDocument.CreateReader();
var namespaceManager = new XmlNamespaceManager(reader.NameTable);
namespaceManager.AddNamespace("", "http://www.w3.org/2000/09/xmldsig#");
var signature = xDocument.XPathSelectElement("/Signature/SignatureValue", namespaceManager);
var x509Certificate = xDocument.XPathSelectElement("/Signature/KeyInfo/X509Data/X509Certificate", namespaceManager);
但签名和 x509Certificate 元素始终为空。
我还尝试直接在 Root 对象上使用该方法,但效果不一样。我做错了什么?
谢谢
这里是一个快速的。您必须为空的默认命名空间提供前缀。它可以是任何东西,在这个例子中我称之为“root”。
using System.Xml;
NameTable nt = new NameTable();
XmlNamespaceManager nsmgr = new XmlNamespaceManager(nt);
nsmgr.AddNamespace("root", "http://www.w3.org/2000/09/xmldsig#");
XmlDocument xml = new XmlDocument();
xml.Load("c:\temp\test.xml");
XmlNode ndSignature = xml.SelectSingleNode("//root:Signature/root:SignatureValue", nsmgr);
XmlNode ndCertificate = xml.SelectSingleNode("//root:Signature/root:KeyInfo/root:X509Data/root:X509Certificate", nsmgr);
Console.WriteLine(ndSignature.InnerText);
Console.WriteLine(ndCertificate.InnerText);
最好用LINQ来XML API.
它自 2007 年起在 .Net Framework 中可用。
c#
void Main()
{
const string filename = @"e:\Temp\pampua84.xml";
XDocument xdoc = XDocument.Load(filename);
XNamespace ns = "http://www.w3.org/2000/09/xmldsig#";
string SignatureValue = xdoc.Descendants(ns + "SignatureValue")
.FirstOrDefault()?.Value;
string X509Certificate = xdoc.Descendants(ns + "X509Certificate")
.FirstOrDefault()?.Value;
Console.WriteLine("SignatureValue='{0}'", SignatureValue);
Console.WriteLine("X509Certificate='{0}'", X509Certificate);
}
我在文件中有这个 xml 文档:
<samlp:AuthnRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_73c4b43a-d201-4990-b656-e6bab19e1c09" Version="2.0" IssueInstant="2021-12-14T08:09:39.816485Z" Destination="https://localhost/idp/sso/post" ForceAuthn="true" AssertionConsumerServiceIndex="0" AssertionConsumerServiceURL="https://localhost:5002/signin-spid" AttributeConsumingServiceIndex="0" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" >
<saml:Issuer NameQualifier="https://localhost:5002" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" >https://localhost:5002</saml:Issuer>
<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/2001/04/xmldsig-more#rsa-sha256" />
<Reference URI="#_73c4b43a-d201-4990-b656-e6bab19e1c09">
<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/2001/04/xmlenc#sha256" />
<DigestValue>.........DigestValue...........</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>..............Signature................</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>...........Certificate.............</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
<samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" />
<saml:Conditions NotBefore="2021-12-14T07:59:39.816485Z" NotOnOrAfter="2021-12-14T08:19:39.816485Z" />
</samlp:AuthnRequest>
我只是想用这段代码获取 SignatureValue 标签值和 X509Certificate 标签值:
var xDocument = XDocument.Load("Request.xml");
var reader = xDocument.CreateReader();
var namespaceManager = new XmlNamespaceManager(reader.NameTable);
namespaceManager.AddNamespace("", "http://www.w3.org/2000/09/xmldsig#");
var signature = xDocument.XPathSelectElement("/Signature/SignatureValue", namespaceManager);
var x509Certificate = xDocument.XPathSelectElement("/Signature/KeyInfo/X509Data/X509Certificate", namespaceManager);
但签名和 x509Certificate 元素始终为空。
我还尝试直接在 Root 对象上使用该方法,但效果不一样。我做错了什么?
谢谢
这里是一个快速的。您必须为空的默认命名空间提供前缀。它可以是任何东西,在这个例子中我称之为“root”。
using System.Xml;
NameTable nt = new NameTable();
XmlNamespaceManager nsmgr = new XmlNamespaceManager(nt);
nsmgr.AddNamespace("root", "http://www.w3.org/2000/09/xmldsig#");
XmlDocument xml = new XmlDocument();
xml.Load("c:\temp\test.xml");
XmlNode ndSignature = xml.SelectSingleNode("//root:Signature/root:SignatureValue", nsmgr);
XmlNode ndCertificate = xml.SelectSingleNode("//root:Signature/root:KeyInfo/root:X509Data/root:X509Certificate", nsmgr);
Console.WriteLine(ndSignature.InnerText);
Console.WriteLine(ndCertificate.InnerText);
最好用LINQ来XML API.
它自 2007 年起在 .Net Framework 中可用。
c#
void Main()
{
const string filename = @"e:\Temp\pampua84.xml";
XDocument xdoc = XDocument.Load(filename);
XNamespace ns = "http://www.w3.org/2000/09/xmldsig#";
string SignatureValue = xdoc.Descendants(ns + "SignatureValue")
.FirstOrDefault()?.Value;
string X509Certificate = xdoc.Descendants(ns + "X509Certificate")
.FirstOrDefault()?.Value;
Console.WriteLine("SignatureValue='{0}'", SignatureValue);
Console.WriteLine("X509Certificate='{0}'", X509Certificate);
}