使用样式表将新元素添加到导入的xsl

时间:2019-04-26 11:32:39

标签: xml xslt import

问题: 我有一个demo.xsl和一个demo2.xsl。我无法修改demo.xsl,并且需要在“数字”中添加新元素(国家/地区)。所以我导入了demo.xsl,我被卡住了。我该如何继续?如何插入新标签?

demo.xsl输出:

   <cars color="green">
      <brand>Suzuki</brand>
      <number>ASD-653</number>
   </cars>

demo2.xsl预期输出:

   <cars color="green">
      <brand>Suzuki</brand>
      <number>ASD-653</number>
         <country>ROM</country>
   </cars>

demo.xsl:

 <xsl:template match="cars[@element-type='recordset']/record">
    <cars>
      <xsl:attribute name="color">
        <xsl:value-of select="color" />
      </xsl:attribute>
      <brand>
        <xsl:value-of select="brand" />
      </brandr>    
      <number>
        <xsl:value-of select="number" />
      </number>
    </cars>
  </xsl:template>

demo2.xsl:

 <xsl:import href="demo.xsl" />

2 个答案:

答案 0 :(得分:1)

您需要添加一个转换步骤:

<xsl:template match="cars[@element-type='recordset']/record">
  <xsl:variable name="import-result">
     <xsl:apply-imports/>
  </xsl:variable>
  <xsl:apply-templates select="$import-result/node()" mode="add"/>
</xsl:template>

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

<xsl:template match="cars" mode="add">
   <xsl:copy>
      <xsl:apply-templates select="@* | node()" mode="#current"/>
      <country>ROM</country>
    </xsl:copy>
</xsl:template>

要使用<xsl:apply-templates select="$import-result/node()" mode="add"/>,您需要XSLT 2处理器或XSLT 1处理器,不需要扩展名即可将带有结果树片段的变量转换为节点集;由于大多数XSLT 1处理器都需要扩展功能,因此您需要将该行更改为

<xsl:apply-templates xmlns:exsl="http://exslt.org/common" select="exsl:node-set($import-result)/node()" mode="add"/>    

如果country元素的值取决于原始record中的数据(例如,子级或属性),则可以将其传递到Apply模板中(例如,对于{{1} } country的属性)

record

并与

一起使用
<xsl:apply-templates select="$import-result/node()" mode="add">
  <xsl:with-param name="country" select="@country"/>
</xsl:apply-templates>

答案 1 :(得分:1)

这就是为什么使用这样的“砖”模板样式不是一个好主意的原因:

  <xsl:template match="cars[@element-type='recordset']/record">
    <cars color="{color}">
      <brand>
        <xsl:value-of select="brand" />
      </brandr>    
      <number>
        <xsl:value-of select="number" />
      </number>
    </cars>
  </xsl:template>

XSLT扩展机制,就像任何具有“继承性”的语言一样,可以作用于“超类”的结果以进行进一步处理(甚至是Martin Honnen's answer提出的第二遍转换)。但是,如果您在导入的样式表中使用此拉样式:

  <xsl:template match="cars[@element-type='recordset']/record">
    <cars color="{color}">
      <xsl:apply-templates/>
    </cars>
  </xsl:template>

  <xsl:template match="record/brand|record/number">
    <xsl:copy-of select="."/>
  </xsl:template>

  <xsl:template match="record/*"/>

然后您可以将其添加到已应用的样式表中

  <xsl:template match="cars[@element-type='recordset']/record">
    <cars color="{color}">
      <xsl:apply-templates/>
      <country>ROM</country>
    </cars>
  </xsl:template>

或者如果country元素可能是record的另一个子元素的结果,则需要一个简单的规则,如下:

  <xsl:template match="record/country">
    <xsl:copy-of select="."/>
  </xsl:template>