无条件遍历XML

时间:2018-12-21 15:38:04

标签: c# xml xpath

我具有以下XML结构,其中包含许多节点<PName>。我需要做的是运行一个Xpath查询匹配条件提取一些数据。运行到下一个节点测试条件,然后返回XPath查询并继续该过程

这是我的XML:

<?xml version="1.0"?>
<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="1234">
          <Details>
            <classification classification="paymenttype" category="Found"/>
            <classification classification="Humor" category="None"/>
            <classification classification="Food" category="Fruit"/>
          </Details>
        </PName>
      </properties>
      <childEvents>
      </childEvents>
    </PName>
  </PList>
</PatientDetailsXML>

这是我的代码:

var query = @"//PName[.//PName[Details/classification[@classification='paymenttype' and @category='Wallet']]]";   
foreach (XmlNode n in docs.SelectNodes(query))
{
    var titlelink = n.SelectSingleNode(".//PName/@title");
    var title = titlelink.Value;
    var bedlink = n.SelectSingleNode(".//Room/@bedType");
    var bed = bedlink.Value;
    // Here I want to run to the very next node <PName> and do 
    // some test's such as `classification='paymenttype' and 
    // @category='Wallet'`, if not true insert some data in XML
    // jump back to the XPATH node (where query was working at 
    // and continue the iteration). 
    // If it matches I fetch some data.
 } 

我真的不知道如何在没有条件的情况下如此强力地导航,想法将不胜感激。

2 个答案:

答案 0 :(得分:1)

您的XPath表达式不正确。
因此,将您的C#代码及其XPath表达式更改为

var query = @"//PName[Details/classification[@classification='paymenttype' and @category='Wallet']]"; 
// This query will select PName nodes with a condition
foreach (XmlNode n in docs.SelectNodes(query))
{
    var titlelink = n.SelectSingleNode("@title");
    var title = titlelink.Value;
    var bedlink = n.SelectSingleNode("../Room/@bedType");
    var bed = bedlink.Value;
}

这应该使您更接近目标。


如果要从另一个PName元素检索节点/值,则也可以使用XPath访问它。例如,要获取具有category属性且值为“ Food”的下一个PName元素的classification属性值,可以在{{1} }循环:

foreach

其输出应为“水果”。

答案 1 :(得分:0)

尝试xml linq:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            XElement plist = doc.Descendants("PList").FirstOrDefault();

            List<XElement> pName = plist.Elements("PName").ToList();

            var results = pName.Select(x => new {
                bedType = (string)x.Descendants("Room").FirstOrDefault().Attribute("bedType"),
                name = (string)x.Descendants("PName").FirstOrDefault().Attribute("title"),
                id = (string)x.Descendants("PName").FirstOrDefault().Attribute("PId"),
            }).ToList();


        }
    }
}