简体   繁体   English

linq查询以解析给定的复杂xml

[英]linq query to parse given complex xml

I have a xml like below with root as rail 我有一个像下面这样的xml,根为rail

        <rail>
        <timetable>
         <trainParts>
              <trainPart id="tp_1" name="1" timetablePeriodRef="ttp_2012_13" categoryRef="cat_Commuter" processStatus="planned" trainNumber="1">
                <operatingPeriodRef ref="Daily" />
                <ocpsTT>
                  <ocpTT ocpType="begin" ocpRef="ocp_SWH">
                    <sectionTT trackInfo="SWH-DM" />
                  </ocpTT>
                  <ocpTT ocpType="stop" ocpRef="ocp_SE">
                     <times arrival="16:16:00" departure="16:18:00" scope="scheduled" />
                    <sectionTT trackInfo="SE-DM" />
                  </ocpTT>
    .
    .
    .
    so on
</ocpsTT>
         </trainPart>
        </trainParts>
        </timetable>
        </rail>

Now like this there are many train numbers whose details I have to parse in one go. 现在像这样,有许多火车号码,我必须一口气解析它们的细节。 I can parse one child and its attributes at a time using linq but i want to parse all the childs and its elements. 我可以使用linq一次解析一个孩子及其属性,但是我想解析所有孩子及其元素。 Say for trainNumer="1" i need to get 说出trainNumer =“ 1”我需要得到

categoryRef
    processStatus

    operatingPeriodRef

    ocpType
    ocpRef
    trackInfo

    arrival
    departure

NOTE: In some cases times tag containing departure arrival is not there 注意:在某些情况下,包含出发到达的标签不存在

I did try to write the code as below: 我确实尝试编写如下代码:

   public void trainDetails(string trainNumber)
            {

                var xdoc = XDocument.Load("Rail.xml");
                XNamespace ad = "http://www.rail.org/schemas/2009";
                 var train = (from t in xdoc.Root.Elements(ad + "timetable")
                         let d = t.Element(ad + "trainParts").Element("trainPart")
                         where (string)t.Attribute("number") == trainNumber 
                         select new
                         {
                             operatingPeriod=(from s1 in d.Elements(ad+"operatingPeriodRef")
                                              operatingref=(string)s1.Attribute("ref")
                                               }).ToList()
                             }
                         select new
                         {
                            trainOcpsTT= (from s2 in d.Elements(ad + "ocpsTT").Elements(ad+"ocpTT")
                                             select new
                                             {
                                                ocpType=(string)s2.Attribute("ocpType"),
                                                ocpRef=(string)s2.Attribute("ocpRef")
                                              }).ToList()
                             }).FirstOrDefault();

        }
           }

I am unable to frame the query properly.. Is it Possible to get all these in one xml linq query itself?How? 我无法正确构建查询框架。是否可以在一个xml linq查询本身中获得所有这些查询? If not then which is the proper approach in this case.. 如果不是,那么在这种情况下是正确的方法。

Here is my proposal: 这是我的建议:

public class TrainInfo
{
    public string categoryRef { get; set; }
    public int trainNumber { get; set; }
    public string processStatus { get; set; }
    public string operatingPeriodRef { get; set; }
    public List<ocpsTTs> ocpsTT { get; set; }
}

public struct ocpsTTs
{
    public string ocpType;
    public string ocpRef;
    public string arrival;
    public string departure;
    public string scope;
    public string trackInfo;
}

class Program
{
    static void Main(string[] args)
    {
        TrainInfo ti = ProcessXml(@"XMLFile1.xml", 1);
    }

    static TrainInfo ProcessXml(string xmlfile, int trainnumber)
    {
        TrainInfo retVal;

        try
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(xmlfile);

            XNamespace xns = "http://www.rail.org/schemas/2009";
            XDocument xdoc = System.Xml.Linq.XDocument.Parse(xmlDoc.InnerXml);

            retVal =
                (from c
                 in xdoc.Root.Elements(xns + "timetable").Elements(xns + "trainParts").Elements(xns + "trainPart")
                 where c.Attribute("trainNumber").Value.Equals(trainnumber.ToString())
                 select new TrainInfo
                 {
                     categoryRef = c.Attribute("categoryRef").Value,
                     trainNumber = Int32.Parse(c.Attribute("trainNumber").Value),
                     processStatus = c.Attribute("processStatus").Value,
                     operatingPeriodRef = c.Element(xns + "operatingPeriodRef").Attribute("ref").Value,
                     ocpsTT = (from tt in c.Elements(xns + "ocpsTT").Descendants(xns + "ocpTT")
                               let timeinfo = tt.Elements(xns + "times").Any()
                               select new ocpsTTs
                               {
                                  ocpType = tt.Attribute("ocpType").Value,
                                  ocpRef = tt.Attribute("ocpRef").Value,
                                  arrival = timeinfo ? tt.Element(xns + "times").Attribute("arrival").Value : string.Empty,
                                  departure = timeinfo ? tt.Element(xns + "times").Attribute("departure").Value : string.Empty,
                                  scope = timeinfo ? tt.Element(xns + "times").Attribute("scope").Value : string.Empty,
                                  trackInfo = tt.Element(xns + "sectionTT").Attribute("trackInfo").Value,
                               }).ToList()
                 }).FirstOrDefault();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            retVal = null;
        }

        return retVal;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM