Обход XML без условий - PullRequest
       2

Обход XML без условий

0 голосов
/ 21 декабря 2018

У меня есть следующая структура 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 голосов
/ 22 декабря 2018

Попробуйте 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();


        }
    }
}
0 голосов
/ 21 декабря 2018

Ваши выражения 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 следующего элемента PName, который имеет атрибут classification со значением «Еда», вы можете использовать это выражение XPath в цикле foreach:

var foodlink = n.SelectSingleNode("ancestor::PName/following-sibling::PName/properties/PName/Details/classification[@classification='Food']/@category");
var food = foodlink.Value;

Его вывод должен быть "Fruit".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...