2017-01-30 85 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