Difference between: child::node() and child::*

后端 未结 2 2116
梦如初夏
梦如初夏 2020-12-24 07:25

I just wrote an XSLT that did not work at first.

I had to rename all children of to :



        
相关标签:
2条回答
  • 2020-12-24 07:57

    child::node() matches any node that's not an attribute node, namespace node, or document node. That means that it does match processing instructions, comments, and text nodes.

    child::* matches only elements.

    See section 5.5.3 of the spec:

    The pattern node() matches all nodes selected by the expression root(.)//(child-or-top::node()), that is, all element, text, comment, and processing instruction nodes, whether or not they have a parent. It does not match attribute or namespace nodes because the expression does not select nodes using the attribute or namespace axes. It does not match document nodes because for backwards compatibility reasons the child-or-top axis does not match a document node.

    Update: Michael's answer inspired the following stylesheet. Use it to test the types of nodes as they're processed:

    <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>
    

    Modify what's matched/selected to test other patterns. For example, the following input:

    <A attr="test" other="val">
      <B/>
      <C>some value</C>
      <!-- a comment -->
      <D/>
    </A>
    

    Produces the following output:

    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  [  
    
      ]    ]    ]  
    

    Special thanks to this page for getting me started on the node-type tests. (It's especially fitting that one of Michael's answers from over six years ago appears there, too.)

    0 讨论(0)
  • 2020-12-24 08:06

    To expand on lwburk's answer, if your XML looks like this:

    <A>
      <B/>
      <C/>
      <D/>
    </A>
    

    Then the A element has 7 child nodes; three of them are elements, four are text nodes. The expression child::node() matches all 7, whereas child::* only matches the elements.

    0 讨论(0)
提交回复
热议问题