简体   繁体   中英

Reading/ Extracting specific elements from XML file C#

I've got a really large and very complex XML file, I only want to extract very specific elements from it. The only elements I would like to retrieve are the Atcocode, NaptanCode, all of the elements in the Descriptor, the Longitude and Latitude from Translation and timing status and bus stop type from Stop classification.

I know VS can automatically generate a class, but this will parse unnecessary details. Any help would be greatly appreciated.

Minimal

Snippet from XML File:

<?xml version="1.0" encoding="utf-8"?>
<NaPTAN xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.naptan.org.uk/" CreationDateTime="2018-03-22T08:59:00" ModificationDateTime="2018-03-22T08:59:00" Modification="new" RevisionNumber="0" FileName="NaPTAN030.xml" SchemaVersion="2.1" xsi:schemaLocation="http://www.naptan.org.uk/ http://www.naptan.org.uk/schema/2.1/NaPTAN.xsd">
  <StopPoints>
    <StopPoint CreationDateTime="2009-07-01T16:36:00" ModificationDateTime="2015-11-03T16:19:00" Modification="revise" RevisionNumber="3" Status="active">
      <AtcoCode>030028280001</AtcoCode>
      <NaptanCode>brkpjmt</NaptanCode>
      <Descriptor>
        <CommonName>Tinkers Corner</CommonName>
        <Landmark>adj Forbury Lane</Landmark>
        <Street>Holt Lane</Street>
        <Indicator>opp</Indicator>
      </Descriptor>
      <Place>
        <NptgLocalityRef>E0053849</NptgLocalityRef>
        <LocalityCentre>0</LocalityCentre>
        <Location>
          <Translation>
            <GridType>UKOS</GridType>
            <Easting>439773</Easting>
            <Northing>165685</Northing>
            <Longitude>-1.42979961186</Longitude>
            <Latitude>51.38882190967</Latitude>
          </Translation>
        </Location>
      </Place>
      <StopClassification>
        <StopType>BCT</StopType>
        <OnStreet>
          <Bus>
            <BusStopType>CUS</BusStopType>
            <TimingStatus>OTH</TimingStatus>
            <UnmarkedPoint>
              <Bearing>
                <CompassPoint>NW</CompassPoint>
              </Bearing>
            </UnmarkedPoint>
          </Bus>
        </OnStreet>
      </StopClassification>
      <StopAreas>
        <StopAreaRef CreationDateTime="2009-07-01T16:46:00" ModificationDateTime="2009-07-01T16:46:00" Modification="new" RevisionNumber="0" Status="active">030G58280001</StopAreaRef>
      </StopAreas>
      <AdministrativeAreaRef>064</AdministrativeAreaRef>
    </StopPoint>
...

For example this was the C# class I had in mind:

class Naptan
    {
        public string AtcoCode { get; set; }
        public string NaptanCode { get; set; }
        public long Latitude { get; set; }
        public long Longitude { get; set; }
        public string TimmingStatus { get; set; }
        public string BusStopType { get; set; }
        public string CommonName { get; set; }
        public string Landmark { get; set; }
        public string Street { get; set; }
        public string Indicator { get; set; }
    }

Complete

Link to the whole XML file in question

Currently, I've tried this approach of turning it into a JSON file and then parsing it into a class, and then manually looping through a list of the objects and generating a new list of objects condensed from the original class.

Current code

EDIT

I've implemented Prateek Deshmukh method, however this doesn't extract the specific elements as asked for so I also had to add in this new code, which I would like to avoid doing, does anyone have any better suggestions?:

NaPTAN tempRawData;
                XmlSerializer serializer = new XmlSerializer(typeof(NaPTAN));
                using (FileStream fileStream = new FileStream(@"F:\DfT1.xml", FileMode.Open))
                {
                    tempRawData = (NaPTAN)serializer.Deserialize(fileStream);
                }

                foreach (var StopPoint in tempRawData.StopPoints)
                {
                    Locations.Add(StopPoint.AtcoCode, new Naptan()
                    {
                        NaptanCode = StopPoint.NaptanCode,
                        Latitude = StopPoint.Place.Location.Translation.Latitude,
                        Longitude = StopPoint.Place.Location.Translation.Longitude,
                        TimmingStatus = StopPoint.StopClassification.OnStreet.Bus.TimingStatus,
                        BusStopType = StopPoint.StopClassification.OnStreet.Bus.BusStopType,
                        CommonName = StopPoint.Descriptor.CommonName,
                        Landmark = StopPoint.Descriptor.Landmark,
                        Street = StopPoint.Descriptor.Street,
                        Indicator = StopPoint.Descriptor.Indicator
                    });
                }

Try following using 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 root = doc.Root;
            XNamespace ns = root.GetDefaultNamespace();

            List<Naptan> atcoCodes = doc.Descendants(ns + "StopPoint").Select(x => new Naptan()
            {
                AtcoCode = (string)x.Element(ns + "AtcoCode"),
                NaptanCode = (string)x.Element(ns + "NaptanCode"),
                Latitude = (double)x.Descendants(ns + "Latitude").FirstOrDefault(),
                Longitude = (double)x.Descendants(ns + "Longitude").FirstOrDefault(),
                TimmingStatus = (string)x.Descendants(ns + "TimingStatus").FirstOrDefault(),
                BusStopType = (string)x.Descendants(ns + "BusStopType").FirstOrDefault(),
                CommonName = (string)x.Descendants(ns + "CommonName").FirstOrDefault(),
                Landmark = (string)x.Descendants(ns + "Landmark").FirstOrDefault(),
                Street = (string)x.Descendants(ns + "Street").FirstOrDefault(),
                Indicator = (string)x.Descendants(ns + "Indicator").FirstOrDefault()
            }).ToList();
        }
    }
    class Naptan
    {
        public string AtcoCode { get; set; }
        public string NaptanCode { get; set; }
        public double Latitude { get; set; }
        public double Longitude { get; set; }
        public string TimmingStatus { get; set; }
        public string BusStopType { get; set; }
        public string CommonName { get; set; }
        public string Landmark { get; set; }
        public string Street { get; set; }
        public string Indicator { get; set; }
    }
}

CS class

Are you looking for such solution? Please see the class it has de-serialized the object

NaPTAN result = (NaPTAN)serializer.Deserialize(fileStream);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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