child::node() 和 child::* 之间的区别

发布于 2024-10-24 11:46:08 字数 1014 浏览 2 评论 0原文

我刚刚写了一个 XSLT,一开始不起作用。

我必须将 的所有子项重命名为

<?xml version="1.0" encoding="utf-8"?>
<Record>
<Recordset>
    <company>102</company>
    <store>1801</store>
    ....
</Recordset>
<Recordset>
....
</Recordset>
</Record>

我使用了以下 XSLT:

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

它可以工作并重命名 的所有子项;。 但首先我在模板中的匹配看起来像这样:

<xsl:template match="Record/Recordset/child::node()">

我的想法是 的每个子节点都是一个节点,因此 node() 是合适的。 它也有效,但它为每个孩子插入了一个额外的

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

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

I had to rename all children of <Recordset> to <C>:

<?xml version="1.0" encoding="utf-8"?>
<Record>
<Recordset>
    <company>102</company>
    <store>1801</store>
    ....
</Recordset>
<Recordset>
....
</Recordset>
</Record>

I used the following XSLT:

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

It works and renames all children of <Recordset> to <C>.
But first my match in the template looked like this:

<xsl:template match="Record/Recordset/child::node()">

My idea was that every child of <Recordset> is a node, thus node() would be appropriate.
It worked too but it inserted an extra <C/> for each child.

What's the difference between child::node() and child::*?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冬天旳寂寞 2024-10-31 11:46:08

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

child::* 仅匹配 元素。

请参阅规范的第 5.5.3 节

模式node()匹配所有节点
通过表达式选择
root(.)//(child-or-top::node()),即
是,所有元素、文本、注释和
处理指令节点,是否
或者他们没有父母。它不
匹配属性或命名空间节点
因为表达式没有选择
使用属性或命名空间的节点
轴。它与文档节点不匹配
因为为了向后兼容
子轴或顶轴不存在的原因
匹配文档节点。

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

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

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

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

产生以下输出:

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  [  

  ]    ]    ]  

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

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>
</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.)

非要怀念 2024-10-31 11:46:08

为了扩展 lwburk 的答案,如果您的 XML 如下所示:

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

那么 A 元素有 7 个子节点;其中三个是元素,四个是文本节点。表达式 child::node() 匹配所有 7 个元素,而 child::* 仅匹配元素。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文