【问题标题】:Select node without a particular child选择没有特定子节点的节点
【发布时间】:2012-05-03 15:09:12
【问题描述】:

例如,我有一个这样的 XML 示例

<a>
    <a1>A1</a1>
        <a11>A11</a11>
    <a2>A2</a2>
    Text <strong>text</strong> text...
<a>

如何使用 XPath 选择节点 a 仅包含

<a>
    <a2>A2</a2>
    Text <strong>text</strong> text...
<a>

【问题讨论】:

    标签: xslt xpath lxml


    【解决方案1】:

    不确定这对您是否足够灵活,但它应该可以帮助您入门

    /a/a1 | a/text() | /a/*[not(starts-with(name(), 'a'))]
    

    您可以在这里轻松玩转它:http://www.xpathtester.com/test

    【讨论】:

    • 不完全是我想要的,但我已经能够修改它。也感谢您的网站
    【解决方案2】:

    XPath 是一种用于 XML 文档的查询语言。这意味着 XPath 表达式只能选择一组节点和/或提取数据。

    记住:XPath 表达式永远不会导致 XML 文档结构的修改(例如删除节点)。

    答案是没有 XPath 表达式会选择您想要的节点,因为 XML 文档中没有这样的节点。

    使用 XSLT 可以轻松实现您想要的,而使用 XQuery 则(不那么容易):

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>
    
     <xsl:template match="node()|@*">
      <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
     </xsl:template>
    
     <xsl:template match="*[starts-with(name(), 'a1')]"/>
    </xsl:stylesheet>
    

    当此转换应用于提供的 XML 文档时:

    <a>
        <a1>A1</a1>
        <a11>A11</a11>
        <a2>A2</a2>     Text 
        <strong>text</strong> text... 
    </a>
    

    产生了想要的正确结果:

    <a>
       <a2>A2</a2>     Text 
        <strong>text</strong> text... 
    </a>
    

    【讨论】:

      【解决方案3】:

      这个 xpath:

      //a[normalize-space(.)='A2 Text text text...']
      

      只会选择:

      <a>
          <a2>A2</a2>
          Text <strong>text</strong> text...
      </a>
      

      XSLT 示例...

      XML 输入

      <doc>
        <a>
          <a1>A1</a1>
          <a11>A11</a11>
          <a2>A2</a2>
          Text <strong>text</strong> text...
        </a>
        <a>
          <a2>A2</a2>
          Text <strong>text</strong> text...
        </a>  
      </doc>
      

      XSLT 1.0

      <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output indent="yes"/>
        <xsl:strip-space elements="*"/>
      
        <xsl:template match="/">
          <xsl:copy-of select="//a[normalize-space(.)='A2 Text text text...']"/>
        </xsl:template>
      
      </xsl:stylesheet>
      

      XML 输出

        <a>
         <a2>A2</a2>
          Text <strong>text</strong> text...
        </a>
      

      【讨论】:

      • 可能是因为 XPath 表达式根本没有选择节点?
      • @DimitreNovaatchev - 也许我误解了这个问题。我认为 OP 有 2 个不同的 &lt;a&gt; 并且只想选择一个。在这种情况下,xpath 确实选择了a 节点。我添加了一个例子来说明我的误解。
      • 如果此答案中的转换应用于问题中提供的 XML 文档,则结果为空字符串。
      • @DimitreNovaatchev - 我用 Xalan、Saxon 6.5.5、Saxon-HE 9.3 和 Saxon-EE 9.3 进行了尝试。一切都为我工作。
      • 是的,但您没有对 OP 提供的 XML 文档应用转换。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-06
      • 2014-07-21
      相关资源
      最近更新 更多