2017-01-30 95 views
0

我有複雜的層次結構的XML文件,我用文檔fileName.xml複製。我想插入一個新的元素到其他元素。目標元素根據輸入文件concat('b_',$id)進行計算。如何將元素插入到xslt中的已標識元素中?

例如filename.xml中

<root> 
<transform id="b_0"> 
    <transform id="b_1"> 
    <transform id="b_2"> 
    <transform id="b_3"/> 
    <transform id="b_4"/> 
    </transform> 
    </transform> 
</transform> 
</root> 

這是示例結果文件:

<root> 
<transform id="b_0"> 
    <transform id="obj_1"/> 
    <transform id="b_1"> 
    <transform id="b_2"> 
    <transform id="b_3"> 
    <transform id="obj_2"/> 
    </transform> 
    <transform id="b_4"/> 
    </transform> 
    </transform> 
</transform> 
</root> 

我的XSLT代碼的模式:

<xsl:variable name="transforms" select="document('fileName.xml')"/> 
<xsl:variable name="table" select="."/> 
<xsl:template match="tr"> 
    <xsl:variable name="param" select="$table//tr/td[2]"/> 
    <xsl:variable name="id" select="concat('b_',$param)"/> 
    <xsl:copy-of select="$transforms"/> 
    <xsl:copy> 
    <Transform> 
    <xsl:attribute name="id"><xsl:value-of select="concat('obj_', position())"/></xsl:attribute> 
    <xsl:apply-templates select="$transforms/transform[@id = $id]"/> 
    </Transform> 
    </xsl:copy> 
</xsl:template> 

回答

0

首先,你很難理解你想要達到的目標不顯示輸入給你轉換(雖然從標籤名稱「表」,「TR」,「TD」,我猜測一個HTML格式表)。

你似乎被一些XSLT的概念混淆:

  • xsl:copy-of -tag副本節點集(你的情況:在$transforms -variable的內容)的輸出
  • xsl:copy - 標籤副本當前標籤(在你的情況下,tr - 標籤,因爲這是由模板匹配)的輸出

另外,請注意:

  • position()將返回其父項內的當前節點(您tr)的相對位置,也許這​​就是你想要的,也許不是
  • $transforms/transform[@id=$id]只會匹配的$transforms頂層transform元素。如果您想匹配任何級別的元素,請使用雙斜槓//

現在,用於將$transform -variable的內容作爲指定,插入一個元素中可以指定一個新的元素,你必須創建:

  • 的身份變換複製輸入到輸出
  • 除非該標籤是在這種情況下,你插入一個新的元素,然後複製

既然你正在尋找的標籤是動態的基礎上,一個你所尋找的,- 變量,這必須作爲參數傳遞。根據你的代碼,我想你想在@id=$id這個元素中插入一個新的元素作爲下面的兄弟。

您可以創建這樣一個與此轉換:

<xsl:template match="node()" mode="tx"> 
    <!-- parameters controlling behaviour as input --> 
    <xsl:param name="id" /> 
    <xsl:param name="pos" /> 
    <!-- copies the current node --> 
    <xsl:copy> 
     <!-- copies attributes of the current node --> 
     <xsl:copy-of select="@*" /> 
     <!-- if the next sibling with tag transform has id=$id, insert a new element --> 
     <xsl:if test="following-sibling::transform[position()=1 and @id=$id]"> 
      <transform> 
       <xsl:attribute name="id"> 
        <xsl:value-of select="concat('obj_', $pos)" /> 
       </xsl:attribute> 
      </transform> 
     </xsl:if> 

     <!-- call recursively, make sure to include the parameters --> 
     <xsl:apply-templates select="node()" mode="tx"> 
      <xsl:with-param name="id" select="$id"/> 
      <xsl:with-param name="pos" select="$pos" /> 
     </xsl:apply-templates> 
    </xsl:copy> 
</xsl:template> 

請注意,我設置這個mode轉化爲能夠控制被調用時,它(我只是希望它在特定情況下調用,而不是在所有輸入)。

這可以從你的變換匹配TR這樣調用:

<xsl:template match="tr"> 
    <xsl:variable name="param" select="$table//tr/td[2]" /> 
    <xsl:variable name="id" select="concat('b_',$param)" /> 

    <xsl:apply-templates select="$transforms" mode="tx"> 
     <xsl:with-param name="id" select="$id"/> 
     <xsl:with-param name="pos" select="position()" /> 
    </xsl:apply-templates> 
</xsl:template> 

一個完全可以工作在這裏例如:http://xsltransform.net/bwdwsA/1