c#.net xpath在遍历时不拾取元素

本文关键字:元素 遍历 net xpath | 更新日期: 2023-09-27 17:58:42

我正在开发一个页面,该页面使用XPATH遍历XML文档以提取某些数据元素并基于它们构建字符串。我能够正确地计数元素,但当试图对它们进行排序遍历时,一些正在计数的元素没有显示出来。最有可能的是,该任务可以更有效地完成,对正确完成该任务的任何帮助都将不胜感激。

XML

<?xml version="1.0" encoding="UTF-16"?>
<Presentation>
    <Filename>Name of file</Filename>
    <version>1.2</version>
    <threshold>23</threshold> <!-- gives number of slides -->
    <Slides>
        <Slide id="slide id">
            <Filename>Name of file</Filename>
            <Title>Title of slide</Title>
        </Slide>
        <Slide id="slide id">
            <Filename>Name of file</Filename>
            <Title>Title of slide</Title>
            <quizobjects>
                <quizobject id="1">
                <filename>Name of quiz</filename>
            </quizobjects>
        </Slide>
        <Slide id="slide id">
            <Filename>Name of file</Filename>
            <Title>Title of slide</Title>
        </Slide>
        ...etc
     </Slides>
</Presentation>

下面是一个XML示例。我遍历幻灯片,数着它们,也数着quizobjects。(这会返回正确的数字)但是,当我遍历所有幻灯片,试图在幻灯片节点中获得每个测验的位置时,它从未命中任何测验对象。

C#

int numSlides;
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlToParse.Text); //pass in xml string
XmlElement root = doc.DocumentElement;
//get number of slides from threshold node
numSlides = Convert.ToInt32(root.SelectSingleNode("//threshold").InnerText);
//get number of quizzes/slides
XmlNodeList xnQuiz = root.SelectNodes("/Presentation/Slides/Slide/quizobjects"); //returns 7
XmlNodeList xnList = root.SelectNodes("/Presentation/Slides/Slide");
int[] quizLocArray = new int[xnQuiz.Count]; //create array to hold location of quizzes
int j = 0;
//find index of quizzes in slide list
for(int i = 0; i < xnList.Count; i++)
{
    XmlNode quiz = xnList[i].SelectSingleNode("/quizobjects");
    if(quiz != null) //stepping through quiz always equals null
    {
        quizLocArray[j] = (i + 1);
        j++;
    }
}

输出

numSlides/XML中的幻灯片总数:23

xnQuiz.Count/XML中的测验总数:7

String.Join(",", quizLocArray)/幻灯片列表中测验的索引数组:0,0,0,0,0,0

c#.net xpath在遍历时不拾取元素

它看起来好像您的XML数据格式不正确,因为您缺少一个关闭的</quizobject>。我会继续假设这只是一个拼写错误。

您需要将XPath查询从SelectSingleNode("/quizobjects")更改为SelectSingleNode("quizobjects")才能获得所需的XML元素。

Presentation.xml文件:

<Presentation>
  <Filename>Name of file</Filename>
  <version>1.2</version>
  <threshold>23</threshold>
  <!-- gives number of slides -->
  <Slides>
    <Slide id="slide id">
      <Filename>Name of file</Filename>
      <Title>Title of slide</Title>
    </Slide>
    <Slide id="slide id">
      <Filename>Name of file</Filename>
      <Title>Title of slide</Title>
      <quizobjects>
        <quizobject id="1">
          <filename>Name of quiz</filename>
        </quizobject>
      </quizobjects>
    </Slide>
    <Slide id="slide id">
      <Filename>Name of file</Filename>
      <Title>Title of slide</Title>
    </Slide>
  </Slides>
</Presentation>

C#代码:

XmlDocument doc     = new XmlDocument();
try
{
    using (var reader = XmlReader.Create("Presentation.xml"))
    {
        int numSlides;
        doc.Load(reader);
        XmlElement root = doc.DocumentElement;
        //get number of slides from threshold node
        numSlides = Convert.ToInt32(root.SelectSingleNode("//threshold").InnerText);
        //get number of quizzes/slides
        XmlNodeList xnQuiz = root.SelectNodes("/Presentation/Slides/Slide/quizobjects");
        XmlNodeList xnList = root.SelectNodes("/Presentation/Slides/Slide");
        //create array to hold location of quizzes
        int[] quizLocArray = new int[xnQuiz.Count];
        int j = 0;
        //find index of quizzes in slide list
        for (int i = 0; i < xnList.Count; i++)
        {
            XmlNode quiz = xnList[i].SelectSingleNode("quizobjects");
            if (quiz != null)
            {
                quizLocArray[j] = (i + 1);
                j++;
            }
        }
    }
}
catch (Exception exception)
{
    Console.WriteLine(exception.Message);
}

两个问题:

  • 在示例XML中,/Presentation/Slides/Slide[id='slide id']/quizobjects/quizobject没有结束标记(本身也不是空标记)
  • quizobjects的最后一个XPath有一个额外的/。将其更改为"quizobjects"即可工作

更改代码:

for(int i = 0; i < xnList.Count; i++)
{
    XmlNode quiz = xnList[i].SelectSingleNode("quizobjects"); // Changed from "/quizobjects"
    if(quiz != null) //stepping through quiz always equals null
    {
        quizLocArray[j] = (i + 1);
        j++;
    }
}

只需将语句中的'/quizobjects'替换为'quizoobjects'即可:

XmlNode quiz = xnList[i].SelectSingleNode("/quizobjects");

希望,它会起作用的。。

当路径以/开头时,它总是将其视为绝对路径。这就是你没有得到元素的原因。