xml XSLT 应用模板选择中的“@*|node()”是什么意思?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11167501/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 13:33:18  来源:igfitidea点击:

What does "@*|node()" in a XSLT apply-template select mean?

xmlxslt

提问by maximus

I read some XSLT examples and found that code:

我阅读了一些 XSLT 示例并发现了以下代码:

<xsl:apply-template select="@*|node()"/>

What does that mean?

这意味着什么?

回答by Tomalak

The XPath expression @* | node()selects the unionof attribute nodes (@*) and all other types of XML nodes (node()).

XPath表达式@* | node()选择联合属性节点(@*)和所有其他类型的XML节点(node())。

It is a shorthand for attribute::* | child::node().

它是 的简写attribute::* | child::node()

In XSLT, XPath is relative to the context nodeand the default selection axisis the childaxis, so the expression

在 XSLT 中,XPath 是相对于上下文节点的,默认选择child轴,因此表达式

  • selectsall attributes and immediate children of the context node (when used as a select="..."expression, for example in <xsl:apply-templates>)
  • matchesall attribute- and other nodes regardless of context (when used as a match=""expression in <xsl:template>) - note that there is a difference between selecting nodes and matching them: the context node only matters for selection.
  • 选择上下文节点的所有属性和直接子节点(当用作select="..."表达式时,例如 in <xsl:apply-templates>
  • 匹配所有属性和其他节点,而不管上下文(当用作 中的match=""表达式时<xsl:template>) - 请注意,选择节点和匹配它们之间存在差异:上下文节点仅对选择很重要。

Imagine the following node is the context node:

想象以下节点是上下文节点:

<xml attr="value">[
  ]<child />[
  ]<!-- comment -->[
  ]<child>
    <descendant />
  </child>[
]</xml>

the expression node()will not only select both <child>nodes, but also four whitespace-only text nodes (signified by [and ]for the sake of visibility) and the comment. The <descendant>is not selected.

该表达式node()不仅会选择两个<child>节点,还会选择四个纯空白文本节点(由[]为了可见性表示)和注释。在<descendant>没有被选中。

A special characteristic of XML is that attribute nodes are notchildren of the elements they belong to (although the parent of an attribute is the element it belongs to).

XML 的一个特殊特性是属性节点不是它们所属元素的子元素(尽管属性的父元素是它所属的元素)。

This asymmetric relationship makes it necessary to select them separately, hence the @*.

这种不对称关系使得有必要分别选择它们,因此@*.

It matches any attribute node belonging to the context node, so the attr="value"will be selected as well.

它匹配属于上下文节点的任何属性节点,因此attr="value"也将被选中。

The |is the XPath union operator. It creates a singe node set from two separate node-sets.

|是XPath联合操作。它从两个单独的节点集创建一个单一的节点集。

<xsl:apply-templates>then finds the appropriate <xsl:template>for every selected node and runs it for that node. This is the template matching part I mentioned above.

<xsl:apply-templates>然后<xsl:template>为每个选定的节点找到合适的并为该节点运行它。这就是我上面提到的模板匹配部分。

回答by Dimitre Novatchev

To add to Tomalak's excellent answer:

添加到 Tomalak 的优秀答案中:

Most ofthen one would see <xsl:apply-template select="@*|node()"/>used in a template like this one:

大多数情况下,人们会<xsl:apply-template select="@*|node()"/>在这样的模板中看到使用

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

This is known as the identity ruleor "identity template".

这称为身份规则或“身份模板”。

One of the most fundamental and powerful XSLT design patterns is the use and overriding of the identity rule.

最基本和最强大的 XSLT 设计模式之一是标识规则的使用和覆盖

If a transformation consists only of the identity rule, the result of the transformation is the source XML document itself -- this is why the template is known as "the identity rule".

如果转换仅包含身份规则,则转换的结果是源 XML 文档本身——这就是模板被称为“身份规则”的原因。

Why is this result produced?

为什么会产生这样的结果?

The short answer is: because of the XSLT processing model.

简短的回答是:因为 XSLT 处理模型。

A more detailed explanation must start from the top:

更详细的解释必须从顶部开始

node()

matches any element, text-node, comment or processing-instruction. The document- (root)-node is also matched by node().

匹配任何元素、文本节点、注释或处理指令。文档(根)节点也与node().

We can imagine the "leaf" nodes of any document tree -- these are any nodes that don't have children themselves such as a text-node, comment and processing-instruction. An empty element should also be considered a leaf node.

我们可以想象任何文档树的“叶”节点——这些节点本身没有子节点,例如文本节点、评论和处理指令。空元素也应视为叶节点。

The identity rule is initially selected for execution (applied) against all children nodes of the document nodes (these are the single top elements and any comments or processing-instruction siblings it could have). The matched node is shallow copied and if it is a non-element leaf node, the <xsl:apply-templates select="node()|@*"/>instruction doesn't select any nodes or attributes.

最初选择标识规则以针对文档节点的所有子节点执行(应用)(这些是单个顶部元素以及它可能具有的任何注释或处理指令兄弟)。匹配的节点是浅复制的,如果它是非元素叶节点,则<xsl:apply-templates select="node()|@*"/>指令不选择任何节点或属性。

If the matched node is an element, it is shallow copied then the <xsl:apply-templates select="node()|@*"/>instruction causes the same template (as there isn't any other template in the transformation code) to be applied against each of its attributes and each of its children nodes.

如果匹配的节点是一个元素,则它是浅复制的,那么该<xsl:apply-templates select="node()|@*"/>指令将导致对其每个属性及其每个子节点应用相同的模板(因为转换代码中没有任何其他模板)。

This is the recursion that drives processing every node of the XML documentuntil leaf nodes or attributes are reached and at which place the <xsl:apply-templates select="node()|@*"/>selects no children or attribute nodes.

这是驱动处理 XML 文档的每个节点的递归,直到到达叶节点或属性,并且在该位置不<xsl:apply-templates select="node()|@*"/>选择子节点或属性节点。

回答by Sean B. Durkin

Congratulations to @Tomalak for the first correct answer. The tick should be going on his answer. I'm just going to add some clarifications to his answer.

恭喜@Tomalak 获得第一个正确答案。滴答声应该在他的回答上。我只是要在他的回答中添加一些说明。

Note One

注意一

... @* | node() selects the union of ...

... @* | node() 选择...的并集

The | operator not just returns the union of the two operands but sorts in document order and removes duplicates. The de-dup part is not relevant here because there are no duplicates to remove, but the sorting part is worth noting. A more correct version would be to say ...

的| 运算符不仅返回两个操作数的并集,而且按文档顺序排序并删除重复项。去重部分在这里不相关,因为没有要删除的重复项,但排序部分值得注意。更正确的版本是说......

... @* | node() selects the union, sorted in document order, of ...

... @* | node() 选择联合,按文档顺序排序,...

Note Two

注二

... and all other types of XML child nodes (node())

...以及所有其他类型的 XML 子节点 (node())

This is broadly true, but is misleading. When most people read "XML child nodes", they think child nodes in the DOM sense. But this is not what is being selected. Only XDM nodes are selected. For an illustration take a look at the following document.

这大体上是正确的,但具有误导性。大多数人在阅读“XML 子节点”时,会想到 DOM 意义上的子节点。但这不是被选中的。仅选择 XDM 节点。有关说明,请查看以下文档。

<?xml version="1.0" encoding="ISO-8859-1"?>
<root-element my-attrib="myattrib-vaue" xmlns:hi="www.abc.com"><child-element />
abc&apos;def
</root-element>

Now suppose the context item is the 'root-element'. A reader of Tomalak's answer is asked the question: what is selected by "@*|node()"? The implication of Tomalak's answer for those thinking of the DOM model, would be that there are 6 things selected:

现在假设上下文项是“根元素”。Tomalak 回答的读者被问到一个问题:“@*|node()”选择了什么?对于考虑 DOM 模型的人来说,Tomalak 的回答意味着选择了 6 件事:

  • The my-attrib attribute
  • The node-space attribute (which is a true attribute in DOM)
  • The child-element node
  • The 'abc' bit
  • The entity reference
  • The 'def' bit.
  • 我的属性
  • 节点空间属性(在 DOM 中是一个真正的属性)
  • 子元素节点
  • 'abc' 位
  • 实体参考
  • 'def' 位。

But this is not actually true in XSLT. What is actually selected is ...

但这在 XSLT 中实际上并非如此。实际选择的是...

  • The my-attrib attribute
  • The child-element node
  • The XDM text node, being the concatination of 3 DOM text nodes like: "abc'def"
  • 我的属性
  • 子元素节点
  • XDM 文本节点,是 3 个 DOM 文本节点的串联,例如:“abc'def”

So a more accurate statement would be ...

所以更准确的说法是......

The XPath expression @* | node() selects the union, sorted in document order, of (attribute nodes of the context item and XML child nodes of the context item in sense of the XDM). The XD model ignores some node types, such as entity definitions, that are in the DOM, and contiguous text DOM nodes are concatenated into one XDM text node.

XPath 表达式@* | node() 选择(在 XDM 意义上的上下文项的属性节点和上下文项的 XML 子节点)的并集,按文档顺序排序。XD 模型会忽略 DOM 中的一些节点类型,例如实体定义,并将连续的文本 DOM 节点连接成一个 XDM 文本节点。