我读了一些XSLT示例,发现代码:
<xsl:apply-template select="@*|node()"/>
Run Code Online (Sandbox Code Playgroud)
那是什么意思?
Tom*_*lak 42
XPath表达式@* | node()选择联合属性节点(的@*)和所有其他类型的XML节点(node()).
这是一个简写attribute::* | child::node().
在XSLT中,XPath是相对于上下文节点的,默认选择轴是child轴,因此表达式
select="..."表达式时,例如在中<xsl:apply-templates>)match=""表达式时<xsl:template>) - 请注意选择节点和匹配它们之间存在差异:上下文节点仅对选择很重要.想象一下,以下节点是上下文节点:
<xml attr="value">[
]<child />[
]<!-- comment -->[
]<child>
<descendant />
</child>[
]</xml>
Run Code Online (Sandbox Code Playgroud)
表达式node()不仅会选择两个<child>节点,还会选择四个仅限空白的文本节点(由可见性表示[并且]为了可见性)和注释.在<descendant>没有被选中.
XML的一个特殊特性是属性节点不是它们所属元素的子节点(尽管属性的父节点是它所属的元素).
这种不对称的关系使得有必要分别选择它们,因此@*.
它匹配属于上下文节点的任何属性节点,因此attr="value"也将选择它.
这|是XPath联合运算符.它从两个独立的节点集创建一个单节点集.
<xsl:apply-templates>然后找到适合<xsl:template>每个选定节点并为该节点运行它.这是我上面提到的模板匹配部分.
Dim*_*hev 16
要添加Tomalak的优秀答案:
大多数人会看到<xsl:apply-template select="@*|node()"/>像这样的模板使用:
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
这称为身份规则或" 身份模板 ".
最基本和最强大的XSLT设计模式之一是使用和覆盖身份规则.
如果转换仅包含标识规则,则转换的结果是源XML文档本身 - 这就是模板被称为"标识规则"的原因.
为什么会产生这种结果?
简短的回答是:因为XSLT处理模型.
更详细的解释必须从顶部开始:
node()
Run Code Online (Sandbox Code Playgroud)
匹配任何元素,文本节点,注释或处理指令.文档 - (根) - 节点也匹配node().
我们可以想象任何文档树的"叶子"节点 - 这些节点本身没有子节点,例如文本节点,注释和处理指令.空元素也应该被视为叶节点.
最初选择标识规则以对文档节点的所有子节点执行(应用)(这些是单个顶部元素以及它可以具有的任何注释或处理指令兄弟节点).匹配的节点是浅复制的,如果它是非元素叶节点,则<xsl:apply-templates select="node()|@*"/>指令不选择任何节点或属性.
如果匹配的节点是一个元素,则它被浅层复制,然后该<xsl:apply-templates select="node()|@*"/>指令导致相同的模板(因为转换代码中没有任何其他模板)应用于其每个属性及其每个子节点.
这是递归,它驱动处理XML文档的每个节点,直到到达叶节点或属性,并且在哪个位置<xsl:apply-templates select="node()|@*"/>选择没有子节点或属性节点.
恭喜@Tomalak获得第一个正确答案.勾号应该是他的回答.我只想对他的回答补充一些说明.
...... @*| node()选择...的并集
| operator不仅返回两个操作数的并集,而且按文档顺序排序并删除重复项.重复部分在这里不相关,因为没有重复删除,但排序部分值得注意.一个更正确的版本就是说......
...... @*| node()选择以文档顺序排序的union ...
...以及所有其他类型的XML子节点(node())
这是大致正确的,但具有误导性.当大多数人阅读"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'def
</root-element>
Run Code Online (Sandbox Code Playgroud)
现在假设上下文项是'root-element'.Tomalak的答案的读者被问到这个问题:"@*| node()"选择了什么?对于那些考虑DOM模型的人来说,Tomalak的答案意味着选择了6件事:
但在XSLT中实际上并非如此.实际选择的是......
所以更准确的陈述是......
XPath表达式@*| node()选择以文档顺序排序的union(上下文项的属性节点和XDM意义上下文项的XML子节点).XD模型忽略DOM中的某些节点类型(例如实体定义),并且连续文本DOM节点连接到一个XDM文本节点中.
| 归档时间: |
|
| 查看次数: |
34309 次 |
| 最近记录: |