我正在使用XPath从XML文档中读取元素。具体来说,我想返回任何元素的值,该元素是指定元素的子元素(这里指定的元素是<SceneryType>
,并且这些元素具有单位数值。所以我想返回{{的所有子元素1}}例如。
这是XML:
<SceneryType> 1
我尝试了各种方法来获取这些子元素,但我无法理解。我的//表达式的目标部分只返回从它看起来的根,但是迭代器没有运行,这似乎很奇怪,如果表达式返回所有元素的节点列表,它不应该遍历每个元素吗?
<MissionObjectives>
<Theme themeName="Gothic">
<SceneryType>
1
<Objective>
Do a river thing.
</Objective>
<Objective>
Get all men to the other side of the river.
</Objective>
</SceneryType>
<SceneryType>
2
<Objective>
Climb some trees!
</Objective>
<Objective>
Shoot the tree!
</Objective>
</SceneryType>
</Theme>
我已经尝试通过Stack Overflow查找类似的问题,但我似乎无法找到适用于XPath的任何内容。我不能为此使用LINQ to XML。知道如何返回各种“目标”节点的所有值吗?
为任何帮助干杯!
答案 0 :(得分:0)
例如,您的xml数据在搜索元素的文本节点中具有回车符,换行符和空格。请记住,XML节点可以是元素,属性或文本(以及其他节点类型)。下面的解决方案有点在“长手”的一面,也许有点“hacky”,但它应该工作。我不确定你是否想要子元素文本数据或整个子元素,但我只返回子文本节点数据(没有回车符和换行符)。此外,尽管此解决方案最严格意义上不使用LINQ to XML,但它确实使用了一个LINQ表达式。
private List<string> getSceneryTypeObjectiveTextList(string xml, int sceneryTypeId, string xpath = "/MissionObjectives/Theme/SceneryType")
{
List<string> result = null;
XmlDocument doc = null;
XmlNodeList sceneryTypeNodes = null;
try
{
doc = new XmlDocument();
doc.LoadXml(xml);
sceneryTypeNodes = doc.SelectNodes(xpath);
if (sceneryTypeNodes != null)
{
if (sceneryTypeNodes.Count > 0)
{
foreach (XmlNode sceneryTypeNode in sceneryTypeNodes)
{
if (sceneryTypeNode.HasChildNodes)
{
var textNode = from XmlNode n in sceneryTypeNode.ChildNodes
where (n.NodeType == XmlNodeType.Text && n.Value.Replace("\r", "").Replace("\n", "").Replace(" ", "") == sceneryTypeId.ToString())
select n;
if (textNode.Count() > 0)
{
XmlNodeList objectiveNodes = sceneryTypeNode.SelectNodes("Objective");
if (objectiveNodes != null)
{
result = new List<string>(objectiveNodes.Count);
foreach (XmlNode objectiveNode in objectiveNodes)
{
result.Add(objectiveNode.InnerText.Replace("\r", "").Replace("\n", "").Trim());
}
// Could break out of the iteration, here, if we know that SceneryType is always unique (i.e. - no duplicates in Element text node)
}
}
}
}
}
}
}
catch (Exception ex)
{
// Handle error
}
finally
{
}
return result;
}
private sampleCall(string filePath, int sceneryTypeId)
{
List<string> compatibleObjectivesList = null;
try
{
compatibleObjectivesList = getSceneryTypeObjectiveTextList(File.ReadAllText(filePath), sceneryTypeId);
}
catch (Exception ex)
{
// Handle error
}
finally
{
}
}
答案 1 :(得分:0)
使用XDocument简单得多:
var doc = XDocument.Load(objectivesPath + "MissionObjectives" + chosenTheme + ".xml");
获取所有第一个SceneryType子节点:
var node = doc.XPathSelectElement("//MissionObjectives/Theme/SceneryType[1]");
获取第二个目标节点:
var node = doc.XPathSelectElement("//MissionObjectives/Theme/SceneryType/Objective[2]");
更多xpath个样本