0

So here's the XML document:

<Ticket>
    <Tickets>
        <Destination>America</Destination>
        <Destination>Italy</Destination>
        <Destination>China</Destination>
    </Tickets>
</Ticket>

In my exercises, it was pretty easy to find out what the destination was, you just make a string like

string xmlString = "Tickets/Ticket/*" 

and run it like so...

But now...

How would I find the price and location of this:

    <Ticket> 
   <Tickets>
     <Destination location ="America">520</Destination>
     <Destination location ="Italy">420</Destination>
     <Destination location ="China">320</Destination>
   </Tickets>
</Ticket>

Finding the price is easy, same as above (first example)... But how do I find what the location is inside that destination tag?

My college gave me exercises like the first example, easy... But when I got to my exam it was similar to the 2nd example... But I don't know what to do? My exam is long done now, so this isn't "cheating" or anything, I'm just curious... Please help? :)

PS: I'm using Visual Studio 2013 Ultimate and coding using C# and using console application, not windows forms... Well, I could use forms but ya... Console is quicker...

James Heffer
  • 686
  • 1
  • 6
  • 17
  • 2
    The first thing to do is get valid XML - what you've got there *isn't* valid. I completely agree that using a console app is a quicker way to demonstrate just one thing, by the way :) I would suggest using LINQ to XML, which is a good, easy-to-use API. Update your question with valid XML and what you've *tried* to get at the relevant information, and it'll be easier to help you. – Jon Skeet Feb 22 '15 at 10:15
  • I doubt that the second piece of xml is valid (or maybe something got lost in the formatting?) – Icepickle Feb 22 '15 at 10:15
  • use something like this – Philip Stuyck Feb 22 '15 at 10:32
  • Forgot the quotes, and I cant really remember EXACTLY how the question was layed out, but it was something similiar to that, basically... I didn't know how to get "America", but to get 520 is easy... – James Heffer Feb 22 '15 at 10:33
  • @JonSkeet "well-formed". Without a schema/DTD no statements about validity can be made. – Tomalak Feb 22 '15 at 10:40
  • And I think I got it... XML document: 520 420 320 – James Heffer Feb 22 '15 at 10:48
  • http://stackoverflow.com/questions/933687/read-xml-attribute-using-xmldocument. One more: http://stackoverflow.com/questions/16370183/easy-xpathnavigator-getattribute. You also can get XPathNavigator from XPathDocument – shameleo Feb 22 '15 at 10:50
  • @Tomalak: Well if it's not even well-formed, it *can't* be valid, can it? Yes, I agree that well-formed is the more technically correct term here - but I suspect it may have confused the OP more than "valid". – Jon Skeet Feb 22 '15 at 12:01
  • @JonSkeet The terms are confused a lot, that's why I marked it as nitpicking. – Tomalak Feb 22 '15 at 12:48

3 Answers3

1

Your XML is not valid. You are missing attribute in Destination element. Assuming you want to read something similar to below:

<Ticket>
 <Tickets>
    <Destination location= "America">520</Destination>
    <Destination location= "Italy">420</Destination>
    <Destination location="China">320</Destination>
  </Tickets>
</Ticket>

You can do it through XmlTextReader:

var reader = new XmlTextReader(@"Data.xml");
while (reader.Read()) {
 reader.MoveToContent();
 if (reader.NodeType == XmlNodeType.Element && reader.Name == "Destination") {
 Console.WriteLine(reader.GetAttribute("location"));
 }
}
Ankit Vijay
  • 3,752
  • 4
  • 30
  • 53
  • I did update my first post with the location attribute... Thank you though – James Heffer Feb 22 '15 at 11:00
  • I would recommend *against* using `XmlTextReader` here. It's useful for very long documents which can't be loaded completely into memory (or where doing so is problematic) but it's *really* painful (and brittle) to use compared with just loading the whole document in with LINQ to XML or something similar. – Jon Skeet Feb 22 '15 at 12:02
0

So this works:

static void Main(string[] args)
        {
            XmlTextReader xReader = new XmlTextReader(@"../../Ticket.xml");
            //xReader.WhitespaceHandling = WhitespaceHandling.None;
            XmlDocument xDoc = new XmlDocument();
            xDoc.Load(xReader);
            //XmlNodeList xNodeList = xDoc.DocumentElement.SelectNodes("//Ticket/Tickets/@*");
            XmlNodeList elemList = xDoc.GetElementsByTagName("Destination");
                for (int i = 0; i < elemList.Count; i++)
                    {
                        string attrVal = elemList[i].Attributes["location"].Value;
                        string elemVal = elemList[i].InnerText.ToString();
                        Console.WriteLine("Location: " + attrVal + " " + "Price: " + elemVal);
                        Console.ReadLine();
                    }  
        }
James Heffer
  • 686
  • 1
  • 6
  • 17
0

In addition to the rest of the answers I will add the following - C# offers four different ways of parsing and handling XML data:

I suggest you read a little bit about all four in order to decide which one you need. They do differ in terms of performance (speed when handling large XML files, memory footprint etc.). XmlDocument and XPath are DOM-based parsing tools, which means that the XML is loaded in your RAM by creating a XML tree with all the objects and their attributes in there. This leads to two things - increased memory footprint when handling large XML documents (approx. 1:10 ration with 1=diskspace the file requires and 10=memory space the DOM requires) but at the same time you can traverse the tree as any tree out there, access all its elements without a problem and so on. XmlReader on the other hand is used to handle XML data in a streaming manner - you parse an element and then, if you haven't stored the data yourself, it's gone. You cannot jump backwards (in this case you have to start over and then iterate until you reach the desired predecessor) and you cannot access a successor directly (unless it's really a direct successor) without iterating through all elements in-between. Speed-wise there have been many discussions but I find all the solutions fast enough for the usual XML-stuff you do in your everyday life. The only big issue one might have is the memory footprint each one produces. Considering the structure of your XML I'd go for the XmlReader.

rbaleksandar
  • 8,713
  • 7
  • 76
  • 161