根据条件读取多个节点

时间:2018-12-21 08:18:20

标签: c# xml linq xpath

我具有以下XML结构。这只是一个提取,文件包含“ PList”下的“ PName”的多个节点。我刚刚在这里显示了两个示例。

问题是我需要提取所有分类属性值为“ paymenttype”且类别属性值为“ Wallet”的节点。然后从结果中提取“标题”,并存储为字典或列表。提取存储后,这就是提取节点之间的比较列表或字典。

<PatientDetailsXML>             
 <PList> 
               <PName type="Patient">
            <properties>
                <Room bedType="Auto" />
                <PName title="Joe Beom" PId="1234">
                    <Details>
                        <classification classification="paymenttype" category="Wallet" />
                        <classification classification="Humor" category="None" />
                        <classification classification="Food" category="Fruit" />
                    </Details>
                </PName>
                </properties>
            <childEvents>
            </childEvents>
        </PName>
                <PName type="Patient">
            <properties>
                <Room bedType="Auto" />
                <PName title="John Bair" PId="5678">
                    <Details>
                        <classification classification="paymenttype" category="Found" />
                        <classification classification="Humor" category="None" />
                        <classification classification="Food" category="Fruit" />
                    </Details>
                </PName>
                </properties>
            <childEvents>
            </childEvents>
        </PName>
</PList>
</PatientDetailsXML> 

我尝试了如下操作,但似乎无法正确完成:

 XElement root = XElement.Load("patientdetails.xml");
       IEnumerable<XElement> tests =

          from el in root.Elements("PName")
          where ((string)el.Element("properties").Element("PName").Element("Details").Element("classification").Attribute("paymenttype") == "EventType") && (string)el.Element("properties").Element("PName").Element("Details").Element("classification").Attribute("category") == "Wallet")

          select el;  



       foreach (XElement el in tests)
        {

         Console.WriteLine (el);
          }

编辑(我的第二次尝试):

XmlTextReader Readers = new XmlTextReader("patientdetails.xml");
       XmlDocument docs = new XmlDocument();
       docs.Load(Readers);


   foreach (XmlNode n in docs.SelectNodes(@"//PName/properties/PName/Details/classification[@classification='paymenttype' and @category='Wallet']"))
   {
                Console.WriteLine(n.ParentNode.ParentNode.OuterXml);
   }

1 个答案:

答案 0 :(得分:2)

我更正了您的第一次尝试(LINQ)。它从所讨论的xml中首先返回<PName type="Patient">

IEnumerable<XElement> tests =
    from el in root.Element("PList").Elements("PName")
    let c = el.Descendants("classification")
    where c.Where(x => x.Attribute("classification").Value == "paymenttype"
                    && x.Attribute("category").Value == "Wallet").Any()
    select el;

然后,您可以迭代tests并提取所需的内容。

foreach (var el in tests)
{
    Console.WriteLine(
        el.Element("properties")
          .Element("PName")
          .Attribute("title")
          .Value);
}

我还纠正了您的第二次尝试(XPath)。它将返回标题值<PName title="Joe Beom" PId="1234">

var query = @"//PName[Details/classification[@classification='paymenttype' and @category='Wallet']]/@title";
foreach (XmlNode n in docs.SelectNodes(query))
{
    Console.WriteLine(n.Value);
}