简体   繁体   English

XML-使用序列化对象上的键获取值的C#通用方法

[英]XML - C# Generic method for getting a Value using a Key on a Serialized Object

I have an xml file that looks like below. 我有一个如下所示的xml文件。 And I want to create a method that would get me the value using the key. 我想创建一种方法,可以使用键为我获取值。

    </cbn:Class>
       <cbt:Students>
          <cbt:Student>
            <cbt:Key>x-param-key-studentName-1</cbt:Key>
            <cbt:Value>x-param-studentSurname-val</cbt:Value>
          </cbt:Student>
          <cbt:Student>
            <cbt:Key>x-param-key-studentName-2</cbt:Key>
            <cbt:Value>x-param- studentSurname-val</cbt:Value>
          </cbt:Student>
        </cbt:Students>
    </cbn:Class>

So, i want to get the valud of studentSurname using as key the studentName . 所以,我想使用studentName作为键来获取studentSurname的值。 The xml is serialized, so I can access for example the Student as an object. xml是序列化的,因此我可以访问例如Student作为对象。 I can get the value of the first student by using the code I have written as below: 我可以使用下面编写的代码来获得第一个学生的价值:

string studentSurname = myData.Class.Students.Student[0].Value;

Where myData is the serialized object. 其中myData是序列化对象。 I would like a more generic method instead of getting just the first student. 我想要一个更通用的方法,而不是仅仅让第一个学生。
EDIT: Another XML 编辑: 另一个XML

<?xml version="1.0" encoding="UTF-8"?>
<cbn:PaidOrderNotification xmlns:cbn="http://*/3.12.0.0/*.xsd">
    <cbn:NotificationDate>2016-07-29T11:59:29.1137865Z</cbn:NotificationDate>
    <cbn:Purchase cbt:Id="95233035" xmlns:cbt="http://xml.*.com/3.12.0.0/*.xsd">
        <cbt:Status>Test Order</cbt:Status>
        <cbt:StatusId>TST</cbt:StatusId>
        <cbt:Items>
            <cbt:Item cbt:RunningNo="1">
                <cbt:ProductId>175358</cbt:ProductId>
                <cbt:ProductReportingGroup>Basic alle Laufzeiten</cbt:ProductReportingGroup>
                <cbt:YourCurrencyId>EUR</cbt:YourCurrencyId>
                <cbt:ProfitCalculation>
                    <cbt:GrossRevenue>566.44</cbt:GrossRevenue>
                </cbt:ProfitCalculation>
                <cbt:YourPrice>
                    <cbt:TotalTotalPrice>
                    </cbt:TotalTotalPrice>
                </cbt:YourPrice>
                <cbt:Deliveries />
                <cbt:Additionals />
                <cbt:ExtraParameters />
            </cbt:Item>
        </cbt:Items>
        <cbt:ExtraParameters>
            <cbt:ExtraParameter>
                <cbt:Key>x-my-key</cbt:Key>
                <cbt:Value> x-my-val</cbt:Value>
            </cbt:ExtraParameter>
        </cbt:ExtraParameters>
    </cbn:Purchase>
</cbn:PaidOrderNotification>

I would like to take from here this value: 我想从这里取这个值:

<cbt:ExtraParameters>
            <cbt:ExtraParameter>
                <cbt:Key>x-didi</cbt:Key>
                <cbt:Value>sfsfd</cbt:Value>
            </cbt:ExtraParameter>
        </cbt:ExtraParameters>

How can i do that? 我怎样才能做到这一点?

Your XML document have namespaces but your example do not includes it, do I had to fake some values. 您的XML文档具有名称空间,但是您的示例不包含名称空间,我是否必须伪造一些值。

Once you have the URI for the namespaces, you can use a XmlNamespaceManager to look into the document with the appropriate qualifier 一旦有了名称空间的URI,就可以使用XmlNamespaceManager来使用适当的限定符来查找文档

var xml = @"
    <cbn:Class xmlns:cbn='something' xmlns:cbt='something-else'>
        <cbt:StudentNr></cbt:StudentNr>
        <cbt:Students>
            <cbt:Student>
                <cbt:Key>x-param-key-studentName-1</cbt:Key>
                <cbt:Value>x-param-studentSurname-val</cbt:Value>
            </cbt:Student>
            <cbt:Student>
                <cbt:Key>x-param-key-studentName-2</cbt:Key>
                <cbt:Value>x-param- studentSurname-val</cbt:Value>
            </cbt:Student>
        </cbt:Students>
    </cbn:Class>";

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

var students = doc.SelectSingleNode("//*[local-name() = 'Students']");
var nsmgr = new XmlNamespaceManager(doc.NameTable);
    nsmgr.AddNamespace("cbt", students.NamespaceURI);

var dictionary =  students.SelectNodes("cbt:Student", nsmgr).OfType<XmlElement>()
    .ToDictionary(student => student.SelectSingleNode("cbt:Key"  , nsmgr).InnerText,
                  student => student.SelectSingleNode("cbt:Value", nsmgr).InnerText);

EDIT: You can do this as well: 编辑:您也可以这样做:

string studentSurname = "";
var dictionary = myData.Class.Students.ToDictionary(student => student.Key, 
                                                    student => student.Value);
var exists = dictionary.TryGetValue("x-param-key-studentName-1", out studentSurname);

EDIT2: Note you have two different cbt:ExtraParameters elements, and the first one is empty. EDIT2:请注意,您有两个不同的cbt:ExtraParameters元素,第一个为空。 I extended the code to work with any cbt:ExtraParameter elements 我扩展了代码以与任何cbt:ExtraParameter元素一起使用

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

var dictionary = doc.SelectNodes("//*[local-name() = 'ExtraParameter']")
    .OfType<XmlElement>()
    .ToDictionary(
        extra => extra.SelectSingleNode("*[local-name() = 'Key'  ]").InnerText,
        extra => extra.SelectSingleNode("*[local-name() = 'Value']").InnerText
    );

var studentSurname = "";
var exists = dictionary.TryGetValue("x-my-key", out studentSurname);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM