从任何可能的子节点中查找特定的父节点

时间:2016-10-21 09:02:04

标签: c# xml linq parsing

刚进入一个新的xml问题我很少被困住。也许有人可以把我推向正确的方向:)

我的XML看起来像这样:

<import xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:///XXXXXXXXX/TraumaSchema.xsd">
    <creationDate>2016-10-18</creationDate>
    <hospitalCode>XXXXXXXXXXXX</hospitalCode>
    <importCasesWithErrors>0</importCasesWithErrors>
    <caseState>1</caseState>
    <caseList>
        <case>
            <patientCode>XXXXXXXXXXX</patientCode>
            <internalPatientId>XXXXXXXXXXXXXXX</internalPatientId>
            <masterData>
                <patient>
                    <age/>
                    <sex>1</sex>
                    <asa>1</asa>
                </patient>
                <accident>
                    <cause>1</cause>
                    <trauma>1</trauma>
                    <dateTime>
                        <date>2016-05-15</date>
                        <time>01:30:00</time>
                    </dateTime>
                </accident>
            </masterData>
            <preClinicalData>
                <alarm>
                    <date>2016-05-15</date>
                    <time>02:00:00</time>
                </alarm>
                <arrival>
                    <date>2016-05-15</date>
                    <time>01:30:00</time>
                </arrival>
                <departure>
                    <date>2016-05-15</date>
                    <time/>
                </departure>
                <vitalSign>
                    <capnometry>0</capnometry>
                    <systolicBloodPressure>
                        <mmHg>140</mmHg>
                    </systolicBloodPressure>
                    <heartRate>
                        <perMinute>130</perMinute>
                    </heartRate>
                    <respiratoryRate>
                        <perMinute>20</perMinute>
                    </respiratoryRate>
                    <oxygenSaturation>
                        <percent>97</percent>
                    </oxygenSaturation>
                </vitalSign>
            ....
            ....
            ....
        </case>
        <case>
            ....
            ....
            ....

XML非常大,有两件事情很重要。有一个元素“caseList”,它包含可变数量的情况 - &gt; “案件”。每个“案例”都包含许多其他元素。焦点中的元素是“ patientCode ”,它包含在任何案例组中。

我需要实现的是从任何可能的子节点开始获取此父元素“ patientCode ”。

我不知道我必须从层次结构的哪个位置开始。我唯一知道的是我需要得到这个特殊的父母。

有人知道如何实现这个目标吗?

非常感谢任何帮助。

亲切的问候 桑德罗

2 个答案:

答案 0 :(得分:0)

尝试这样的代码。如果代码结构正确,则无需获取父

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

namespace ConsoleApplication21
{
    class Program
    {
        const string FILEName = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILEName);

            XElement caseList = doc.Descendants().Where(x => x.Name.LocalName == "caseList").FirstOrDefault();
            XNamespace ns = caseList.GetDefaultNamespace();

            var results = caseList.Descendants(ns + "case").Select(x => new {
                masterData = x.Descendants(ns + "masterData").Select(y => new {
                    age = y.Descendants(ns + "age").Select(z => z.IsEmpty  ? null : (int?)z).FirstOrDefault(),
                    sex = (int?)y.Descendants(ns + "sex").FirstOrDefault(),
                    asa = (int?)y.Descendants(ns + "asa").FirstOrDefault(),
                    cause = (int?)y.Descendants(ns + "cause").FirstOrDefault(),
                    trauma = (int?)y.Descendants(ns + "trauma").FirstOrDefault(),
                    date = (DateTime) y.Descendants(ns + "date").FirstOrDefault() + ((DateTime)(y.Descendants(ns + "time").FirstOrDefault())).TimeOfDay,
                }).FirstOrDefault(),
                preClinicalData = x.Descendants(ns + "masterData").Select(y => new {
                    alarm = (DateTime) y.Descendants(ns + "date").FirstOrDefault() + ((DateTime)(y.Descendants(ns + "time").FirstOrDefault())).TimeOfDay,
                    arrival = (DateTime)y.Descendants(ns + "date").FirstOrDefault() + ((DateTime)(y.Descendants(ns + "time").FirstOrDefault())).TimeOfDay,
                    departure = (DateTime)y.Descendants(ns + "date").FirstOrDefault() + ((DateTime)(y.Descendants(ns + "time").FirstOrDefault())).TimeOfDay,
                    capnometry = (int?)x.Descendants(ns + "capnometry").FirstOrDefault(),
                    mmHg = (int?)x.Descendants(ns + "mmHg").FirstOrDefault(),
                    heartRate = (int?)x.Descendants(ns + "heartRate").FirstOrDefault(),
                    respiratoryRate = (int?)x.Descendants(ns + "respiratoryRate").FirstOrDefault(),
                    oxygenSaturation = (int?)x.Descendants(ns + "oxygenSaturation").FirstOrDefault(),                    
                }).FirstOrDefault()
            }).ToList();


        }
    }

}

答案 1 :(得分:0)

<强>更新

好的,我有另一个想法:

我知道选择了哪个节点。有了这个,我可以像这样获得根的路径

var element = doc.Descendants(GetSelectedNode()).First();
var names = element.AncestorsAndSelf()
             .Reverse()
             .Skip(1) // Skip the root
             .Select(x => x.Name);
var joined = string.Join("/", names);

现在包含了这样的根路径,例如:

caseList/case/preClinicalData/therapy/catecholamines (-> a selected node)

现在的问题是我需要跟进路径,将“patientCode”元素放在“case” - 节点的正下方。

如何使用xPath跟踪检索到的路径来获取相关的元素数据?