【问题标题】:XPath expression /node()[1] selects more than the first node?XPath 表达式 /node()[1] 选择的不是第一个节点?
【发布时间】:2017-01-20 01:36:54
【问题描述】:

我有一个文件doc.xml

<?xml version="1.0"?>
<!-- This is the first top-level node -->
<!-- This is the second top-level node -->
<ThirdNode/>
<!-- This is the fourth top-level node -->

我想从文档中选择第一个顶级节点,在firstnode.xsl

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/node()[1]">First</xsl:template>
    <xsl:template match="@*|node()">
        <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
    </xsl:template>
</xsl:stylesheet>

当我运行xsltproc firstnode.xsl doc.xml 时,我得到:

<?xml version="1.0"?>
FirstFirst<ThirdNode/><!-- This is the fourth top-level node -->

… 而不是预期的输出:

<?xml version="1.0"?>
First
<!-- This is the second top-level node -->
<ThirdNode/>
<!-- This is the fourth top-level node -->

为什么/node()[1] 选择器不仅仅匹配第一条评论?如何选择文档的第一个节点(无论是注释、元素还是其他)?

【问题讨论】:

  • 试试(/node())[1]
  • @eLRuLL 我试过了,得到了xsltCompilePattern : failed to compile '(/node())[1]'
  • 备案:xsltproc 是针对 libxml 20902、libxslt 10128 和 libexslt 817 编译的; libxslt 10128 是针对 libxml 20902 编译的; libexslt 817 是针对 libxml 20902 编译的

标签: xml xslt xpath predicate


【解决方案1】:

我已经设法使用libxlt 处理器重现了您的问题,但没有使用XalanSaxon - 这使我得出结论,这是不合格的行为。

将匹配模式更改为:

<xsl:template match="node()[not(parent::*)][1]">

似乎绕过了这个问题。


令人惊讶的是,甚至在您的原始表达式中添加了虚假条件,例如:

<xsl:template match="/node()[not(0)][1]">

甚至:

<xsl:template match="/node()[1][1]">

也可以,所以这显然是一个错误。

【讨论】:

    【解决方案2】:

    我不确定我是否正确理解了您的问题。但是,我试图重现您的问题,结果是这样的:

    Input.xml

    <?xml version="1.0"?>
    <First>
      <Second>
        <ThirdNode/>      
        <Fourth />
      </Second>
    </First>
    

    Processing.xslt

    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
        <xsl:template match="/node()[1]">First1
          <xsl:apply-templates select="node()|@*" />
        </xsl:template>
    
        <xsl:template match="@*|node()">
            <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
        </xsl:template>
    
    </xsl:stylesheet>
    

    输出

    <?xml version="1.0"?>
    First1
    
      <Second>
        <ThirdNode/>      
        <Fourth/>
      </Second>
    

    也许这对你有所帮助。

    【讨论】:

      猜你喜欢
      • 2012-09-23
      • 1970-01-01
      • 1970-01-01
      • 2013-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-03
      • 2022-08-16
      相关资源
      最近更新 更多