1

I have this xml file and I want to extract author name and access number and what I have is a very naive implementation in C# where I am using xml reader and reading line by line. But I am looking for an implementation where I can read the author name and access number in c# efficiently. I am new to C# and I have been told that LINQ should be used but looking at the document and this file I am not able to relate how to use Xdocument. Any help will be appreciated.

<xml>
<records>
<record>
<database name="CP_EndnoteLibrary_2012-2015-1.enl" path="C:\Users\Downloads\file.enl">file.enl</database>
<source-app name="EndNote" version="17.4">EndNote</source-app>
<rec-number>24</rec-number>
<contributors>
<authors>
<author>
<style face="normal" font="default" size="100%">ABCD, X.</style>
</author>
<author>
<style face="normal" font="default" size="100%">EFGH, I.</style>
</author> 
</authors>
</contributors>
<accession-num>
<style face="normal" font="default" size="100%">12345678</style>
</accession-num>
</record>
<record>...</record>
</records>

Following a document, I was able to write this code to figure out author name.

{
    class Program
    {
        static void Main(string[] args)
        {
        XmlReader reader = XmlReader.Create("C:\\Users\\ile_xml.xml");
        while(reader.Read())
        {
            if((reader.NodeType == XmlNodeType.Element) && (reader.Name == "author"))
            {
                reader.Read();
                reader.Read();
                if((reader.NodeType == XmlNodeType.Element) && (reader.Name == "style") && reader.HasAttributes)
                {
                    var val = reader.ReadInnerXml();
                    Console.WriteLine("Display:" + reader.GetAttribute("author"));
                }
            }
        }
    }
}

}

The above code seems to be very inefficient and I am looking for ways to improve this or do it in a better way.

yguw
  • 856
  • 6
  • 12
  • 32

2 Answers2

0
    //Helpfull namespaces:
using System.Xml.Linq;
using System.Xml.XPath;
using System.Xml.Serialization;

        static void Main(string[] args)
    {
        //Your snippet, which didn't work on my machine:
        XmlReader reader = XmlReader.Create("C:\\Users\\Public\\ile_xml.xml");
        while (reader.Read())
        {
            if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "author"))
            {
                reader.Read();
                reader.Read();
                if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "style") && reader.HasAttributes)
                {
                    var val = reader.ReadInnerXml();
                    Console.WriteLine("Display:" + reader.GetAttribute("author"));
                }
            }
        }
        //Should produce the results you are looking for:
        XmlNodeList xmlNodeList;
        XmlDocument xDoc = new XmlDocument();
        XmlReaderSettings xrs = new XmlReaderSettings();
        xrs.DtdProcessing = DtdProcessing.Parse;

        //Get Authors from XML Source
        using (XmlReader reader2 = XmlReader.Create("C:\\Users\\Public\\ile_xml.xml"))
        {
            xDoc.Load(reader2);
            xmlNodeList = xDoc.SelectNodes("records/record/contributors/authors/author");
        }
        foreach (XmlNode node in xmlNodeList)
        {
            Console.WriteLine(node.InnerText);//.InnerXML to include style tags.
        };
    }

xpath will help find the information you need. Hopefully the above will get you closer with xdoc.

Another pattern I have recently adopted is to serialize the xml into c# class (or in this case a List) and then use LINQ to manipulate as desired.

this was helpful to me: Deserializing XML to Objects in C#

Community
  • 1
  • 1
Paul
  • 176
  • 3
  • 16
  • I have sample code to use xcode but I am not sure how to implement it for my input xml file. I will try to use this as sample and see if I can figure out the solution. Thanks! – yguw Nov 15 '15 at 04:50
0

This will give you the correct result:-

XDocument xdoc = XDocument.Load(@"YourXMLfilePath");
var result = xdoc.Root.Elements("record")
                      .Select(x => new
                                 {
                                    Name = (string)x.Element("database").Attribute("name"),
                                    Number = (string)x.Element("rec-number")
                                 });
Rahul Singh
  • 21,585
  • 6
  • 41
  • 56