質問

I am having troubles listing the right values from entered value from console. My XML file is:

<Students>
  <Student>
    <Name>Name1</Name>
    <Surname>Surname1</Surname>
    <Index>2222</Index>
    <Subject name="History">
      <Class>Class2</Class>
      <Status status="passed">
        <Grade>A</Grade>
      </Status>
    </Subject>
  </Student>
  <Student>
    <Name>Name2</Name>
    <Surname>Surname2</Surname>
    <Index>3333</Index>
    <Subject name="Math">
      <Class>Class3</Class>
      <Status status="passed">
        <Grade>D</Grade>
      </Status>
    </Subject>
  </Student>
</Students>

So what I am trying to do is when I enter for example 3333, I want to list the class where the student belongs, in this case is "Class3". My code is like this:

    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.Load("Students.xml");

    Console.WriteLine("\nInsert Index Number");
    string result = Console.ReadLine();

    XmlNodeList xnList = xmlDoc.SelectNodes("//Student/Index");

    XmlNodeList xnList2 = xmlDoc.SelectNodes("//Student/Subject/Class");
    string result2 = null;
    for (int i = 0; i < xnList.Count; i++)
    {
        string nodeval = xnList[i].InnerText;
        if (nodeval == result)
        for (int j = 0; j < xnList2.Count; j++)
        {
                result2 = xnList2[j].InnerText;
                Console.WriteLine("Result" + result2);
        }
    }

}

Any help? Thanks

役に立ちましたか?

解決

Below is your answer. Which basically says you want all Class nodes where it has a parent Index node with the value "3333". You don't need to do your nested FOR loop with 2 node sets to find the match.

 /Students/Student//Class[../..//Index[.="3333"]]
 or
 /Students/Student//Class[../../Index[.="3333"]]
 or
 //Student//Class[../../Index[.="3333"]]

You can test this at the URL http://www.xpathtester.com/test Paste my XPath Expression in the XPath Text Box and your XML in the XML large text box then click "Test!" button.

If you need the complete source code, it is below. The key is to create the correct XPATH expression and doing a string replacement/concatenation with the varying value you call "Index". This returns all Class nodes with the value inputted from the Command Line that you call Index.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load("Students.xml");

            Console.WriteLine("\nInsert Index Number");
            string index = Console.ReadLine();

            //the critical piece is here, creating the correct xpath expression
            string xPathString = String.Format("/Students/Student//Class[../..//Index[.=\"{0}\"]]", index);

            XmlNodeList nodeList = xmlDoc.SelectNodes(xPathString);
            foreach (XmlNode node in nodeList)
            {
                Console.WriteLine("Index: {0} Class: {1}", index, node.InnerText);
            }
            Console.ReadLine();
        }
    }

}

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top