XPath 1.0:选择具有给定父节点的所有子节点,如果父节点没有这样的子节点,则选择空?
使用XPath 1.0和下面的XML,如何选择所有具有“b”父节点的“c”节点,如果“b”父节点没有“c”节点,则选择“”,即获取XPath 1.0:选择具有给定父节点的所有子节点,如果父节点没有这样的子节点,则选择空?,xpath,vtd-xml,Xpath,Vtd Xml,使用XPath 1.0和下面的XML,如何选择所有具有“b”父节点的“c”节点,如果“b”父节点没有“c”节点,则选择“”,即获取{“c1”、“”、“c3”}作为结果节点集(按文档顺序) 我正在使用VTD-XML2.11(Java),我正在寻找一个XPath计算,它将返回上述结果,而不会循环 <a> <b> <c>c1</c> </b> <b/> <b> <c>c3&l
{“c1”、“”、“c3”}
作为结果节点集(按文档顺序)
我正在使用VTD-XML2.11(Java),我正在寻找一个XPath计算,它将返回上述结果,而不会循环
<a>
<b>
<c>c1</c>
</b>
<b/>
<b>
<c>c3</c>
</b>
</a>
c1
c3
我浏览了这些问题,找到了一些有趣的建议,比如奥利弗·贝克尔的方法,但到目前为止我还没有找到解决办法
任何帮助都将不胜感激
谢谢。你用什么来评估这些XPath?我想不出一个好的方法,但是根据您使用的方法,可以很容易地选择所有
b
s,对它们进行迭代,并对每个值使用c值或空白值
这不是一个很好的方法,但它适用于您的示例输入:
//b/c | //b[not(*)] | //b[not(c) and *]/text()
<root>
<item>c1</item>
<item></item>
<item>c3</item>
</root>
解释是:
- 选择a
b下的所有b
sc
- 如果没有子元素,请选择任何
元素本身b
- 选择没有子项的任何
s的第一个文本节点b
b
都将至少有一个文本节点,并且其中的第一个节点将完全是空白,那么这将起作用
使用XSLT进行验证:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<root>
<xsl:for-each select="//b/c | //b[not(*)] | //b[not(c) and *]/text()[1]">
<item>
<xsl:value-of select="."/>
</item>
</xsl:for-each>
</root>
</xsl:template>
</xsl:stylesheet>
在示例输入上运行时的输出:
//b/c | //b[not(*)] | //b[not(c) and *]/text()
<root>
<item>c1</item>
<item></item>
<item>c3</item>
</root>
c1
c3
像这样的东西
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using System.IO;
namespace Xpath
{
class Program
{
static void Main(string[] args)
{
string xml = @"<a>
<b>
<c>c1</c>
</b>
<b/>
<b>
<c>c3</c>
</b>
<b>x</b>
</a>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string xpath = "//b/c/text()|//b[count(child::*) = 0]|//b[count(child::*) = 0]/text()";
StringReader stringReader = new StringReader(xml);
XmlReader xmlReader = XmlReader.Create(stringReader);
XPathDocument xpathDoc = new XPathDocument(xmlReader);
XPathNavigator xpathNav = xpathDoc.CreateNavigator();
XPathNodeIterator xpathIter = xpathNav.Select(xpath);
foreach (XPathNavigator navigator in xpathIter)
{
if (navigator.ValueType == typeof(string))
{
Console.WriteLine("'" + navigator.Value + "'");
}
}
}
}
}
不幸的是,当我使用VTD-XML2.11(Java)运行它时,它会返回
“c1”、“c3”和“
。我不认为这是XPath应该产生的结果(它应该按照文档顺序选择节点),但我想不出比这更好的方法了。您不想使用循环有什么原因吗?有没有办法用VTD-XML做到这一点?不知道为什么VTD-XML不按文档顺序选择节点在这种情况下,好问题。基本上,我希望使用一个通用循环来计算多个XPath表达式,每个表达式都会产生一个结果列表,因此不能根据表达式使用自定义解析逻辑。当我运行它时(使用我的原始XML),这会返回“c1”、“c3”、““”、”
,不幸的是,使用VTD-XML 2.11(Java)。是否希望xpath返回节点集或字符串作为结果?我正在寻找xpath求值以返回由{“c1”、“”、“c3”}
字符串组成的节点集。节点的顺序重要吗?是,(文档)顺序重要。出于性能原因,vtd xml不能保证文档的顺序,除非评估过程自然地导致它。。。我将不得不考虑这个问题,看看我是否能为你提供一些答案