使用XPath 1.0和下面的XML,如何选择具有“b”父级的所有“c”节点,如果“b”父级没有“c”节点,则选择“”,即get {{ 1}}作为结果节点集(按文档顺序)?
我正在使用VTD-XML 2.11(Java),我正在寻找一个单独的XPath评估,它将返回上述结果而不会循环。
{"c1", "", "c3"}
我已经浏览过这些问题并找到了有趣的指针,例如Oliver Becker的方法,但到目前为止我还没有找到解决方案。
任何帮助都将不胜感激。
感谢。
答案 0 :(得分:1)
您使用什么来评估这些XPath?我无法想出一个好方法,但根据您使用它的方法,可以很容易地选择所有b
,迭代它们,并使用c或a的值每个空白值。
这不是一个很好的方法,但它适用于您的样本输入:
//b/c | //b[not(*)] | //b[not(c) and *]/text()
解释是:
c
b
b
个元素b
个孩子的任何c
的第一个文本节点。这将假设任何带有子元素的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>
在样本输入上运行时的输出:
<root>
<item>c1</item>
<item></item>
<item>c3</item>
</root>
答案 1 :(得分:0)
这样的东西?
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 + "'");
}
}
}
}
}
输出是:
'c1'
''
'c3'
'x'