代码之家  ›  专栏  ›  技术社区  ›  user726720

根据条件读取多个节点

  •  2
  • user726720  · 技术社区  · 7 年前

    我有以下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 回复  |  直到 7 年前
        1
  •  2
  •   qwermike    7 年前

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

    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);
    }