получение свойств и атрибутов из XML с помощью Linq в C#

#c# #xml #linq #namespaces

Вопрос:

У меня есть сгенерированный XML и мне нужно извлечь свойства атрибуты и логические значения

 {<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». Для того, чтобы получить список тех, для всех сертификатов в магазине.
Но все они приводят к нулю. Поэтому я совершаю одну и ту же ошибку во всех случаях. Есть идеи, как это сделать?

Комментарии:

1. Создайте классы и десериализуйте в них свой xml, у вас будет все, что вы хотите.

2. вы можете использовать xml-десериализатор следующим образом c-sharpcorner.com/article/simple-xml-parser-in-C-Sharp

3. Спасибо за ваше предложение по десериализации. Я тоже пробовал это, но он не может обрабатывать объем данных, особенно строку 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 }
 

Комментарии:

1. Отлично смотрится, теперь мне нужно выяснить, как заставить это работать для XElement вместо XDocument, потому что XML генерируется в XElement.

2. Рад слышать, что предлагаемое решение работает на вас. Пожалуйста, не забудьте отметить это как ответ.

3. Да, я заставил его работать, удалив .Root. Большое тебе спасибо Ицак

Ответ №2:

Атрибуты в вашем примере не находятся в пространстве имен, поэтому PropertyElement.Attribute(ns "Key") , безусловно, неправильно, если это то, что ns вы также используете для выбора узлов элементов, это должно быть просто PropertyElement.Attribute("Key").Value == "trustAnchor" или (string)PropertyElement.Attribute("key") == "trustAnchor" .

Комментарии:

1. Спасибо, в этом вы правы. Но теперь мой вывод-System.Xml.Linq. XContainer <getElements>d__39

2. Что произойдет, если вы получите доступ, например value.propBool , в foreach ?

3. Какой тип данных вам нужен/вы хотите вернуть? Вы ищете «trustAnchor», но хотите, чтобы это значение также присутствовало в результате?

4. Приставка. WriteLine($»IENUMERABLE: {value.propBool}»); дает ту же систему.Xml.Linq. XContainer <getElements>d__39. Мне нужен сам атрибут, чтобы жало оставалось неизменным и было ли оно истинным или ложным. Таким образом, в конце концов, список всех сертификатов (base64 sting, который хранится в «Закодированном» и который декодируется здесь, в решении) с их свойствами и являются ли они истинными или ложными.

5. Теперь все заработало. Спасибо за вашу помощь!