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
它看起来好像您的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");
希望,它会起作用的。。
当路径以/开头时,它总是将其视为绝对路径。这就是你没有得到元素的原因。