区别:child :: node()和child ::*

Pet*_*ter 22 xslt

我刚刚写了一个起初不起作用的XSLT.

我不得不重新命名的所有儿童<Recordset><C>:

<?xml version="1.0" encoding="utf-8"?>
<Record>
<Recordset>
    <company>102</company>
    <store>1801</store>
    ....
</Recordset>
<Recordset>
....
</Recordset>
</Record>
Run Code Online (Sandbox Code Playgroud)

我使用了以下XSLT:

<xsl:template match="Record/Recordset/child::*">    
    <xsl:element name="C">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

它的工作原理和重命名的所有孩子<Recordset><C>.但首先我在模板中的匹配看起来像这样:

<xsl:template match="Record/Recordset/child::node()">
Run Code Online (Sandbox Code Playgroud)

我的想法是每个孩子<Recordset>都是一个节点,因此node()是合适的.它也有效,但它<C/>为每个孩子插入了额外的东西.

child::node()和之间有什么区别child::*

Way*_*ett 37

child::node()匹配任何不是属性节点,命名空间节点或文档节点的节点.这意味着它确实匹配处理指令,注释和文本节点.

child::*匹配元素.

见规范5.5.3节:

模式node()匹配由表达式root(.)//(child-or-top :: node())选择的所有节点,即所有元素,文本,注释和处理指令节点,无论它们是否有一个父母.它与属性或命名空间节点不匹配,因为表达式不使用属性或命名空间轴选择节点.它与文档节点不匹配,因为出于向后兼容性原因,child-or-top轴与文档节点不匹配.

更新: Michael的回答启发了以下样式表.使用它来测试处理节点的类型:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/|node()">
        <xsl:call-template name="type" />
        <xsl:text>  [  </xsl:text>
        <xsl:value-of select="." />
        <xsl:text>&#10;</xsl:text>
        <xsl:apply-templates select="node()" />
        <xsl:text>  ]  </xsl:text>
    </xsl:template>
    <xsl:template name="type">
        <xsl:choose>
            <xsl:when test="count(.|/)=1">
                <xsl:text>Root</xsl:text>
            </xsl:when>
            <xsl:when test="self::*">
                <xsl:text>Element </xsl:text>
                <xsl:value-of select="name()" />
            </xsl:when>
            <xsl:when test="self::text()">
                <xsl:text>Text</xsl:text>
            </xsl:when>
            <xsl:when test="self::comment()">
                <xsl:text>Comment</xsl:text>
            </xsl:when>
            <xsl:when test="self::processing-instruction()">
                <xsl:text>PI</xsl:text>
            </xsl:when>
            <xsl:when test="count(.|../@*)=count(../@*)">
                <xsl:text>Attribute</xsl:text>
            </xsl:when>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

修改匹配/选择的内容以测试其他模式.例如,以下输入:

<A attr="test" other="val">
  <B/>
  <C>some value</C>
  <!-- a comment -->
  <D/>
</A>
Run Code Online (Sandbox Code Playgroud)

产生以下输出:

Root  [  

  some value



Element A  [  

  some value



Text  [  

  ]  Element B  [  
  ]  Text  [  

  ]  Element C  [  some value
Text  [  some value
  ]    ]  Text  [  

  ]  Comment  [   a comment 
  ]  Text  [  

  ]  Element D  [  
  ]  Text  [  

  ]    ]    ]  
Run Code Online (Sandbox Code Playgroud)

特别感谢这个让我开始进行节点类型测试的页面.(特别适合迈克尔六年前的答案也出现在那里.)


Mic*_*Kay 19

要扩展lwburk的答案,如果您的XML看起来像这样:

<A>
  <B/>
  <C/>
  <D/>
</A>
Run Code Online (Sandbox Code Playgroud)

然后A元素有7个子节点; 其中三个是元素,四个是文本节点.表达式child::node()匹配所有7,而child::*只匹配元素.

  • 在每个`">"之后,在下一个"<"之前,有一些空格.有四个这样的间隙,每个间隙都是一个只有空格的文本节点. (4认同)