2

使用 XPath 1.0 和下面的 XML,我如何选择所有具有“b”父级的“c”节点,如果“b”父级没有“c”节点,则选择“”,即{"c1", "", "c3"}作为结果节点-设置(按文档顺序)?

我正在使用 VTD-XML 2.11 (Java),我正在寻找一个 XPath 评估,它将返回上述结果而无需循环。

<a>
  <b>
    <c>c1</c>
  </b>
  <b/>
  <b>
    <c>c3</c>
  </b>
</a>

我浏览了问题并找到了一些有趣的指针,例如 Oliver Becker 的方法,但到目前为止我还没有找到解决方案。

任何帮助,将不胜感激。

谢谢。

4

2 回答 2

1

您使用什么来评估这些 XPath?我想不出一个很好的方法,但是根据您使用的内容,选择所有bs,遍历它们,并为每个使用 c 的值或空白值可能很容易。

这不是一个好方法,但它适用于您的示例输入:

//b/c | //b[not(*)] | //b[not(c) and *]/text()

解释是:

  • 选择ca下的所有sb
  • b如果元素没有子元素,则选择它们本身
  • b选择任何没有c子节点的 s 的第一个文本节点。

假设任何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>
于 2013-02-05T16:53:50.657 回答
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'
于 2013-02-05T17:15:13.607 回答