如何在 XML 中获取元素属性的值

Posted

技术标签:

【中文标题】如何在 XML 中获取元素属性的值【英文标题】:How can I get value of element attribute in XML 【发布时间】:2021-08-07 10:52:52 【问题描述】:

请问如何获取此 XML 中元素 StatusCode 的属性值:

<LogoutResponse 
    ID="_f525259e-7e91-4282-9dc3-a0da65a4a17a" 
    Version="2.0" 
    IssueInstant="2021-05-17T15:41:55Z" 
    InResponseTo="_5089729f-5cc0-4a66-a3c1-e710cde92897" 
    Destination="https://idp.xyz/logout.aspx" 
    xmlns="urn:oasis:names:tc:SAML:2.0:protocol">
    <Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">https://abc.xyz/api</Issuer>
    <Status>
        <StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
    </Status>
</LogoutResponse>

【问题讨论】:

处理XML的API有多种;你用的是哪个?你试过什么?例如,你看过XDocument 吗?或者XmlDocument(这是一个完全独立的API来做同样的事情),或者XmlSerializer? 这能回答你的问题吗? Getting attribute using XPath @MarcGravell 任何XDocumentXmlDocument。但是名称空间有些东西,我不知道如何正确编写代码。请查看@Krishna Muppalla 代码现在可以工作,我不知道为什么。 【参考方案1】:

由于命名空间,这有点混乱:

var doc = new XmlDocument();
doc.LoadXml(@"<LogoutResponse 
    ID=""_f525259e-7e91-4282-9dc3-a0da65a4a17a""
    Version=""2.0"" 
    IssueInstant=""2021-05-17T15:41:55Z"" 
    InResponseTo=""_5089729f-5cc0-4a66-a3c1-e710cde92897""
    Destination=""https://idp.xyz/logout.aspx"" 
    xmlns=""urn:oasis:names:tc:SAML:2.0:protocol"">
    <Issuer xmlns=""urn:oasis:names:tc:SAML:2.0:assertion"">https://abc.xyz/api</Issuer>
    <Status>
        <StatusCode Value=""urn:oasis:names:tc:SAML:2.0:status:Success"" />
    </Status>
</LogoutResponse>");

var ns = new XmlNamespaceManager(doc.NameTable);
ns.AddNamespace("oasis", "urn:oasis:names:tc:SAML:2.0:protocol");
var attr = (XmlAttribute)doc.SelectSingleNode(
    "/oasis:LogoutResponse/oasis:Status/oasis:StatusCode/@Value", ns);
System.Console.WriteLine(attr.Value);

【讨论】:

【参考方案2】:

您可以尝试使用 XmlDocument。

注意:因为你有一个命名空间(xmlns ...)你的xml中的所有元素 默认情况下在名称空间中。因此你得到对象引用 错误。我已经更新了代码和 .netfiddle。请看一下

var xml = @"<LogoutResponse 
ID=""_f525259e-7e91-4282-9dc3-a0da65a4a17a"" 
Version=""2.0"" 
IssueInstant=""2021-05-17T15:41:55Z"" 
InResponseTo=""_5089729f-5cc0-4a66-a3c1-e710cde92897"" 
Destination=""https://idp.xyz/logout.aspx"" 
xmlns=""urn:oasis:names:tc:SAML:2.0:protocol"">
<Issuer xmlns=""urn:oasis:names:tc:SAML:2.0:assertion"">https://abc.xyz/api</Issuer>
<Status>
<StatusCode Value=""urn:oasis:names:tc:SAML:2.0:status:Success"" />
</Status>
</LogoutResponse>";

var doc = new System.Xml.XmlDocument();                
doc.LoadXml(xml);

var nsManager = new XmlNamespaceManager(doc.NameTable);
nsManager.AddNamespace("ns", "urn:oasis:names:tc:SAML:2.0:protocol");

var result = doc.SelectSingleNode("/ns:LogoutResponse/ns:Status/ns:StatusCode/@Value", nsManager).InnerText;
Console.WriteLine(result);

【讨论】:

谢谢,但这不起作用 - 有一些与命名空间有关的东西。您的代码因 NullReferenceException 而失败。见dotnetfiddle.net/cWHnzk @PavelHodek 请查看更新后的帖子【参考方案3】:

通过使用 LINQ to XML API。

自 2007 年起在 .Net Framework 中可用。

c#

void Main()

    XDocument xdoc = XDocument.Parse(@"<LogoutResponse xmlns='urn:oasis:names:tc:SAML:2.0:protocol' 
        Destination='https://idp.xyz/logout.aspx' ID='_f525259e-7e91-4282-9dc3-a0da65a4a17a' 
        InResponseTo='_5089729f-5cc0-4a66-a3c1-e710cde92897' IssueInstant='2021-05-17T15:41:55Z' Version='2.0'>
        <Issuer xmlns='urn:oasis:names:tc:SAML:2.0:assertion'>https://abc.xyz/api</Issuer>
        <Status>
            <StatusCode Value='urn:oasis:names:tc:SAML:2.0:status:Success'></StatusCode>
        </Status>
    </LogoutResponse>");

    XNamespace ns1 = "urn:oasis:names:tc:SAML:2.0:protocol";

    string StatusCodeValue = xdoc.Descendants(ns1 + "StatusCode")
        .Attributes("Value")
        .FirstOrDefault()?.Value;

    Console.WriteLine("StatusCodeValue='0'", StatusCodeValue);

输出

StatusCodeValue='urn:oasis:names:tc:SAML:2.0:status:Success'

【讨论】:

以上是关于如何在 XML 中获取元素属性的值的主要内容,如果未能解决你的问题,请参考以下文章

获取元素的值并使其成为 XSLT 中属性的值?

获取 XML 中属性的值

如何从动态对象中获取反序列化的 xml 属性

使用 Java 解析 XML 并获取元素值和属性值

Vue。如何在创建的元素中获取“键”属性的值

如何在具有 xmlns 属性的 xml 中使用 xpath 获取特定的嵌套元素? [复制]