tags:

views:

99

answers:

3

Here's my XML file:

<?xml version="1.0" encoding="utf-8" ?>
<Hero>
  <Legion>
    <Andromeda>
      <HeroType>Agility</HeroType>
      <Damage>39-53</Damage>
      <Armor>3.1</Armor>
      <MoveSpeed>295</MoveSpeed>
      <AttackType>Ranged(400)</AttackType>
      <AttackRate>.75</AttackRate>
      <Strength>16</Strength>
      <Agility>27</Agility>
      <Intelligence>15</Intelligence>
      <Icon>Images/Hero/Andromeda.gif</Icon>
    </Andromeda>
    <WitchSlayer>
      <HeroType>Agility</HeroType>
      <Damage>39-53</Damage>
      <Armor>3.1</Armor>
      <MoveSpeed>295</MoveSpeed>
      <AttackType>Ranged(400)</AttackType>
      <AttackRate>.75</AttackRate>
      <Strength>16</Strength>
      <Agility>27</Agility>
      <Intelligence>15</Intelligence>
      <Icon>Images/Hero/Andromeda.gif</Icon>
    </WitchSlayer>
  </Legion>
</Hero>

Here's my method, but it isn't working so I don't know what to do.

public string GetHeroIcon(string Name)
    {
        //Fix later. Load the XML file from resource and not from the physical location.
        HeroInformation = new XPathDocument(@"C:\Users\Sergio\Documents\Visual Studio 2008\Projects\Erth v0.1[WPF]\Tome of Newerth v0.1[WPF]\InformationRepositories\HeroRepository\HeroInformation.xml");
        Navigator = HeroInformation.CreateNavigator();

        Navigator.MoveToRoot();
        Navigator.MoveToChild("Witch","Legion");
        string x = "";

        do
        {
            x += Navigator.Value;
        } while (Navigator.MoveToNext());

        return x;
    }

I need help making a method that recieves a string parameter "Name" and then return all of the attributes of the XML element.

In pseudo-code:

public void FindHero(string HeroName)
{
    //Find the "HeroName" element in the XML file.
    //For each tag inside of the HeroName parent element,
    //add it to a single string and blast it out through a MessageBox.
}

I'm LEARNING how to use this, please don't leave snobby remarks like, "we won't do this for you." I'm not asking for something groundbreaking here, just a simple use case for what I need on my program and for my learning nothing else. :D I'm doing the whole app in WPF and I can literally say that I've not done ONE single thing with previous knowledge, I'm doing this just to learn new things in my spare time.

Thanks a bunch SO, you rock!

+2  A: 
private static string GetHeroIcon(string name)
{
    XDocument doc = XDocument.Load("C:/test.xml");
    return doc.Descendants(name).Single().Element("Icon").Value;
}
Yuriy Faktorovich
XDocument makes this much easier.
Mark Ewer
A: 

First off, since you've tagged this question WPF, you should know that WPF has excellent support for binding directly to XML data. You can then for instance map an image in the GUI directly to the Icon element in the XML file. See this link for example: http://www.longhorncorner.com/UploadFile/cook451/DataBindingXAML12102005134820PM/DataBindingXAML.aspx (first hit on google for "wpf databinding xml")

From code, you can create an XPathDocument from your XML file, then get a Navigator and finally run custom XPath queries on it, like so:

// Get's the value of the <icon> tag for a hero
var node = myNavigator.SelectSingleNode("/Legion/Hero/" + nameOfHero + "/Icon");    
var icon = node.Value;
// To get all the nodes for that hero, you could do
var nodeIter = myNavigator.Select("/Legion/Hero/" + nameOfHero)
var sb = new StringBuilder();
while (nodeIter.MoveNext())
{
    sb.AppendLine(nodeIter.Current.Name + " = " + nodeIter.Current.Value);
}
MessageBox.Show(sb.ToString());

See this kb article for an example.

Isak Savo
A: 

DISCLAIMER: I copied and pasted the code from my code and did some refactoring in this window. It may not compile on first run but that may mean that it takes 10 minutes to get it to where it needs to be.

I would strongly recommend that you use XML deserialization. It's object oriented, type-safe, and just flat out slick.

Try this: 1) Create a series of classes: One for Hero, Legion, Witchslayer, and Andromeda.

Here is an example of the Andromeda class:

using System.Xml.Serialization;

[XmlRoot( "Andromeda" )]
public class Andromeda
{
   [XmlElement( "Damage" )]
   public String Damage
   {
      get;set;
   }

   [XmlElement( "Armor" )]
   public double Armor
   {
      get;set;
   }
}

The Hero class should contain an instance of Legion and Legion should contain the rest to mimic the layout of the XML packet.

2) Use the XmlSerializer to deserialize the data:

XmlSerializer xmlSerializer = new XmlSerializer( typeof( Hero ) );

using ( StringReader reader = new StringReader( xmlDataString ) )
{
    Hero hero = ( Hero ) xmlSerializer.Deserialize( reader );
}

If you set it up right, you'll be left with a hero instance that contains the nested objects and all of the data. Cool, huh?

asteio