簡體   English   中英

XSLT apply-template select中的“@ * | node()”是什么意思?

[英]What does “@*|node()” in a XSLT apply-template select mean?

我讀了一些XSLT示例,發現代碼:

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

那是什么意思?

XPath表達式@* | node() @* | node()選擇屬性節點(的結合 @* )和所有其他類型的XML節點( node()

它是attribute::* | child::node()的簡寫 attribute::* | child::node()

在XSLT中,XPath是相對於上下文節點的 ,默認選擇child軸,因此表達式

  • 選擇上下文節點的所有屬性和直接子節點(當用作select="..."表達式時,例如在<xsl:apply-templates>
  • 匹配所有屬性和其他節點而不管上下文(當用作<xsl:template>match=""表達式時) - 請注意選擇節點和匹配它們之間存在差異:上下文節點僅對選擇很重要。

想象一下,以下節點是上下文節點:

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

表達式node()不僅會選擇兩個<child>節點,還會選擇四個僅空白文本節點(為了可見性而用[]表示)和注釋。 未選擇<descendant>

XML的一個特殊特征是屬性節點不是它們所屬元素的子節點(盡管屬性的父節點是它所屬的元素)。

這種不對稱關系使得有必要分別選擇它們,因此@*

它匹配屬於上下文節點的任何屬性節點,因此也將選擇attr="value"

| 是XPath聯合運算符。 它從兩個獨立的節點集創建一個單節點集。

<xsl:apply-templates>然后為每個選定的節點查找相應的<xsl:template>為該節點運行它。 這是我上面提到的模板匹配部分。

要添加Tomalak的優秀答案:

大多數人會看到像這樣的模板中使用的<xsl:apply-template select="@*|node()"/>

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

這稱為身份規則或“ 身份模板 ”。

最基本和最強大的XSLT設計模式之一是使用和覆蓋身份規則

如果轉換僅包含標識規則,則轉換的結果是源XML文檔本身 - 這就是模板被稱為“標識規則”的原因。

為什么會產生這種結果?

簡短的回答是 :因為XSLT處理模型。

更詳細的解釋必須從頂部開始

node()

匹配任何元素,文本節點,注釋或處理指令。 document-(root)-node也與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&apos;def
</root-element>

現在假設上下文項是'root-element'。 Tomalak的答案的讀者被問到這個問題:“@ * | node()”選擇了什么? 對於那些考慮DOM模型的人來說,Tomalak的答案意味着選擇了6件事:

  • my-attrib屬性
  • node-space屬性(DOM中的true屬性)
  • 子元素節點
  • 'abc'位
  • 實體參考
  • 'def'位。

但在XSLT中實際上並非如此。 實際選擇的是......

  • my-attrib屬性
  • 子元素節點
  • XDM文本節點,是3個DOM文本節點的連接,如:“abc'def”

所以更准確的陳述是......

XPath表達式@ * | node()選擇以文檔順序排序的union(上下文項的屬性節點和XDM意義上下文項的XML子節點)。 XD模型忽略DOM中的某些節點類型(例如實體定義),並且連續文本DOM節點連接到一個XDM文本節點中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM