在 C# 中使用 Linq 从 XML 获取属性和属性

Posted

技术标签:

【中文标题】在 C# 中使用 Linq 从 XML 获取属性和属性【英文标题】:get properties and attributes from XML using Linq in C# 【发布时间】:2021-11-23 10:09:30 【问题描述】:

我有一个生成的 XML,需要提取属性属性和 BooleanValues

<l7:Resource xmlns:l7="http:not shown for security reasons">
  <l7:TrustedCertificate id="not shown for security reasons" version="0">
    <l7:Name>not shown for security reasons</l7:Name>
    <l7:CertificateData>
      <l7:IssuerName>not shown for security reasons</l7:IssuerName>
      <l7:SerialNumber>not shown for security reasons</l7:SerialNumber>
      <l7:SubjectName>not shown for security reasons</l7:SubjectName>
      <l7:Encoded>not shown for security reasons</l7:Encoded>
    </l7:CertificateData>
    <l7:Properties>
      <l7:Property key="revocationCheckingEnabled">
        <l7:BooleanValue>true</l7:BooleanValue>
      </l7:Property>
      <l7:Property key="trustAnchor">
        <l7:BooleanValue>true</l7:BooleanValue>
      </l7:Property>
      <l7:Property key="trustedAsSamlAttestingEntity">
        <l7:BooleanValue>false</l7:BooleanValue>
      </l7:Property>
      <l7:Property key="trustedAsSamlIssuer">
        <l7:BooleanValue>false</l7:BooleanValue>
      </l7:Property>
      <l7:Property key="trustedForSigningClientCerts">
        <l7:BooleanValue>true</l7:BooleanValue>
      </l7:Property>
      <l7:Property key="trustedForSigningServerCerts">
        <l7:BooleanValue>false</l7:BooleanValue>
      </l7:Property>
      <l7:Property key="trustedForSsl">
        <l7:BooleanValue>false</l7:BooleanValue>
      </l7:Property>
      <l7:Property key="verifyHostname">
        <l7:BooleanValue>false</l7:BooleanValue>
      </l7:Property>
    </l7:Properties>
  </l7:TrustedCertificate>
</l7:Resource>  

我尝试了很多解决方案,例如


            public static void GetPropertiesWithAttributes(XElement certlist, XNamespace ns, IEnumerable<XElement> certProperties)
        


            var propellor = from prop in certlist.Elements(ns + "Properties").Take(10)

                            select new
                            
                                propAtt = (string)prop.Elements(ns + "Property").SingleOrDefault(PropertyElement => PropertyElement.Attribute(ns + "Key").Value == "trustAnchor"),

                                propBool = prop.Element(ns + "BooleanValue").Value
                            ;

            foreach (var value in propellor)
            
                Console.WriteLine($"IENUMERABLE: value");
            
        

所以我需要提取像“trustAnchor”这样的属性和像“true”这样的BooleanValue。为了获得商店中所有证书的列表。 但它们都导致null。所以我在所有情况下都犯了同样的错误。任何想法如何使这项工作?

【问题讨论】:

创建类并将你的 xml 反序列化为它,你会得到任何你想要的。 你可以像这样使用xml反序列化器c-sharpcorner.com/article/simple-xml-parser-in-C-Sharp 感谢您对反序列化的建议。我也试过了,但它无法处理大量数据,尤其是 base64 字符串,它非常大。 【参考方案1】:

请尝试以下解决方案。

c#

void Main()

    XDocument doc = XDocument.Parse(@"<l7:Resource xmlns:l7='http:not shown for security reasons'>
            <l7:TrustedCertificate id='not shown for security reasons' version='0'>
                <l7:Name>not shown for security reasons</l7:Name>
                <l7:CertificateData>
                    <l7:IssuerName>not shown for security reasons</l7:IssuerName>
                    <l7:SerialNumber>not shown for security reasons</l7:SerialNumber>
                    <l7:SubjectName>not shown for security reasons</l7:SubjectName>
                    <l7:Encoded>not shown for security reasons</l7:Encoded>
                </l7:CertificateData>
                <l7:Properties>
                    <l7:Property key='revocationCheckingEnabled'>
                        <l7:BooleanValue>true</l7:BooleanValue>
                    </l7:Property>
                    <l7:Property key='trustAnchor'>
                        <l7:BooleanValue>true</l7:BooleanValue>
                    </l7:Property>
                    <l7:Property key='trustedAsSamlAttestingEntity'>
                        <l7:BooleanValue>false</l7:BooleanValue>
                    </l7:Property>
                    <l7:Property key='trustedAsSamlIssuer'>
                        <l7:BooleanValue>false</l7:BooleanValue>
                    </l7:Property>
                    <l7:Property key='trustedForSigningClientCerts'>
                        <l7:BooleanValue>true</l7:BooleanValue>
                    </l7:Property>
                    <l7:Property key='trustedForSigningServerCerts'>
                        <l7:BooleanValue>false</l7:BooleanValue>
                    </l7:Property>
                    <l7:Property key='trustedForSsl'>
                        <l7:BooleanValue>false</l7:BooleanValue>
                    </l7:Property>
                    <l7:Property key='verifyHostname'>
                        <l7:BooleanValue>false</l7:BooleanValue>
                    </l7:Property>
                </l7:Properties>
            </l7:TrustedCertificate>
        </l7:Resource>");

    XNamespace ns = doc.Root.GetNamespaceOfPrefix("l7");

    var propellor = doc.Descendants(ns + "Property")
        .Where(d => d.Attribute("key").Value.Equals("trustAnchor"))
        .Take(10)
        .Select(prop => new
        
            propAtt = (string)prop.Attribute("key").Value,
            propBool = prop.Element(ns + "BooleanValue").Value
        );

    foreach (var value in propellor)
    
        Console.WriteLine($"IENUMERABLE: value");
    

输出

IENUMERABLE:  propAtt = trustAnchor, propBool = true 

【讨论】:

现在看起来很棒我必须弄清楚如何让它为 XElement 而不是 XDocument 工作,因为 XML 是生成到 XElement 中的。 很高兴听到建议的解决方案对您有用。请不要忘记将其标记为答案。 是的,我通过删除 .Root 让它工作了。非常感谢伊扎克【参考方案2】:

您的示例中的属性不是在命名空间中,所以PropertyElement.Attribute(ns + "Key") 肯定是错误的,如果那是您也用来选择元素节点的ns,它应该只是PropertyElement.Attribute("Key").Value == "trustAnchor"(string)PropertyElement.Attribute("key") == "trustAnchor"

【讨论】:

谢谢,你说得对。但我现在的输出是 System.Xml.Linq.XContainer+d__39 如果您访问例如会发生什么value.propBoolforeach? 您需要/想要返回的数据类型是什么?您正在查找“trustAnchor”,但希望该值也出现在结果中? Console.WriteLine($"IENUMERABLE: value.propBool");给出相同的 System.Xml.Linq.XContainer+d__39。我需要属性本身,因此刺痛因此锚定它是真还是假。因此,最后列出了所有证书(base64 字符串,存储在“编码”中,并在解决方案中的其他地方解码)及其属性以及它们是真还是假。 现在可以使用了。感谢您的帮助!

以上是关于在 C# 中使用 Linq 从 XML 获取属性和属性的主要内容,如果未能解决你的问题,请参考以下文章

使用 Linq 从在线 XML 文件中读取数据

使用 LINQ 从具有嵌套数组的类中获取子属性值和父属性值

LINQ to XML:如何在 C# 中获取元素值?

用于 XML 的 C# LINQ Left Outer Join 无法正常工作

如何从 C# 中的 xml 元素中获取最高值?

C# Linq to XML 读取多个带有属性的标签