1

I am trying to get some data from an XML document. I have no control over the schema. If it were up to me I would have chosen another schema. I am using C#'s XPATH library to get the data.

XML DOC

<Journals>
    <name>Title of Journal</name>
    <totalvolume>2</totalvolume>
    <JournalList>
        <Volume no="1">
            <Journal>
                <issue>01</issue>
                <Title>Title 1</Title>
                <date>1997-03-10</date>
                <link>www.somelink.com</link>
            </Journal>
            <Journal>
                <issue>02</issue>
                <Title>Title 3</Title>
                <date>1997-03-17</date>
                <link>www.somelink.com</link>
            </Journal>
        </Volume>
        <Volume no="2">
            <Journal>
                <issue>01</issue>
                <Title>Title 1</Title>
                <date>1999-01-01</date>
                <link>www.somelink.com</link>
            </Journal>
            <Journal>
                <issue>01</issue>
                <Title>Title 2</Title>
                <date>1999-01-08</date>
                <link>www.somelink.com</link>
            </Journal>
        </Volume>
    </JournalList>
 </Journals>

I am trying to get all the data in the Volume 2 node. Here is what I tried so far:

C# Code:

protected void loadXML(string url)
{
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.Load(url);

    string strQuery = "Volume[@no='2']";

    XmlElement nodeList = xmlDoc.DocumentElement;
    XmlNodeList JournalList = nodeList.SelectNodes(strQuery);

    foreach (XmlElement Journal in JournalList)
    {
        XmlElement temp = Journal;
    }
}

It seems there are no nodes in JournalList. Anyone? Thanks in advance/

2
  • Note that using an XDocument is easier than an XmlDocument. With XmlDocument you are basically limited to using XPath queries, whereas with XDocument you can use LINQ. Commented Jan 4, 2015 at 4:40
  • @slugster LINQ is nice and all, but it's not inherently better. XPath can handle this situation (and many much more complex ones) with ease. Commented Jan 4, 2015 at 7:17

2 Answers 2

1

Your code is looking for "Volume" nodes directly under the "Journals" node

Change this:

string strQuery = "Volume[@no='2']";

To this, in order to look for "Volume" nodes under the "JournalList" node:

string strQuery = "JournalList/Volume[@no='2']";

Also, there's a couple typos in your XML:

</Volume no="2">  ->  <Volume no="2">   // no open tag found

</Journal>        ->  </Journals>       // expecting end tag </Journals>

From your comment below:

how would I go about access each journal? for example. I want irrate through each "journal" and get the title of the journal?

In order to do that, you could modify your code slightly:

var nodeList = xmlDoc.DocumentElement;
var volume = nodeList.SelectSingleNode(strQuery);
foreach (XmlElement journal in volume.SelectNodes("Journal"))
{
    var title = journal.GetElementsByTagName("Title")[0].InnerText;
}
Sign up to request clarification or add additional context in comments.

3 Comments

thanks for response, but i have a questions. how would I go about access each journal? for example. I want irrate through each "journal" and get each journal title within Volume 2? I want to use a foreach statement, but it seems i am only i am grabbed Volume 2. How would I go about getting the nodes within it?
@Grant I believe your second code sample contains a mistake. Shouldn't you iterate over xmlDoc.SelectNodes("//JournalList/Volume[@no=2]") instead of over volume.SelectNodes("Journal")?
Ah, I see. It's implemented a bit more complicated than it needs to be, but it would work. xmlDoc.SelectNodes("//JournalList/Volume[@no = 2]/Journal") would select the wanted nodes straight-away, saving a few lines.
0

Also you can use Linq to XML:

using System.Xml.Linq;
//...
string path="Path of your xml file"
XDocument doc = XDocument.Load(path);
var volume2= doc.Descendants("Volume").FirstOrDefault(e => e.Attribute("no").Value == "2");

1 Comment

doc.Descendants("Volume").FirstOrDefault(e => e.Attribute("no").Value == "2") - 77 characters. doc.SelectNodes("//Volume[@no=2]") - 34 characters, and easier to read.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.