0

Currently I am trying to randomly select a name from an XML list and print it in the Console. However, the node seems to always be null. My XML Looks like this:

<?xml version="1.0" encoding="utf-8"?>
<XnaContent xmlns:ns="Microsoft.Xna.Framework">
  <Asset Type="Object">

    <nameData>
      <firstName>
        <name>Charles</name>
        <name>David</name>
        <name>Bob</name>
        <name>John</name>
      </firstName>
    </nameData>


  </Asset>
</XnaContent>

And C#:

//create XML document 
XmlDocument doc = new XmlDocument();

//load in XML file to doc
doc.Load("Content/XML/Names.xml");

Random rand = new Random();
int count = 1;

//Set count to be the number of name nodes in the first name field
count = doc.SelectNodes("//firstName/name").Count;

//set randVal so it never exceeds amount of name nodes
int randVal = rand.Next(count);

// set objNode to the name at position()
XmlNode objNode = doc.SelectSingleNode("/nameData/firstName/name[position() = " + rand + "]");

//Write the randomly chosen name to console
Console.WriteLine(objNode.InnerText);

Thanks in advance for your help

Gilad Green
  • 36,708
  • 7
  • 61
  • 95
  • 2
    Possible duplicate of [XML Document SelectSingleNode returns null](http://stackoverflow.com/questions/17161317/xml-document-selectsinglenode-returns-null) – Gilad Green Aug 02 '16 at 07:04
  • `/...` selects *from the root node*, so `/nameData` doesn't exist, does it? – Charles Mager Aug 02 '16 at 07:06

2 Answers2

1

2 problems:

  1. you add the rand instead of the randVal to the XPath string
  2. you should start your XPath with // instead of / (just like you did in the Count

Change from:

objNode = doc.SelectSingleNode("/nameData/firstName/name[position() = " + rand + "]");

To:

objNode = doc.SelectSingleNode("//nameData/firstName/name[position() = " + randVal + "]");

You can also remove the position() funtion and leave it like this:

"//nameData/firstName/name[" + randVal + "]"
Gilad Green
  • 36,708
  • 7
  • 61
  • 95
0

Guild's answer shows you how to fix your problem, but another option is to remove your reliance on XPath entirely:

var doc = XDocument.Load("Content/XML/Names.xml");

var names = doc.Descendants("name")
    .Select(x => x.Value)
    .ToList();

var rand = new Random();

var name = names[rand.Next(names.Count)];
Charles Mager
  • 25,735
  • 2
  • 35
  • 45
  • Regarding using XDocument.Load: I don't believe Monogame allows for this namespace... Or, at least, I can't seem to get it to work. – Chris Lyons Aug 02 '16 at 07:23
  • @ChrisLyons I'll admit I'm not that familiar. A quick search seems to show it works, though: you'd need a reference to `System.Xml.Linq.dll` and a `using System.Xml.Linq` statement in your file. – Charles Mager Aug 02 '16 at 07:26
  • Referencing those give this error: "The type or namespace name 'Linq' does not exist in the namespace 'System.Xml' (are you missing an assembly reference?)" – Chris Lyons Aug 02 '16 at 07:31