Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 如何在最内层添加新节点_Xml_Xslt - Fatal编程技术网

Xml 如何在最内层添加新节点

Xml 如何在最内层添加新节点,xml,xslt,Xml,Xslt,在my xsl中,已经为para、graphic等元素定义了模板。示例如下: <xsl:template match="para"> <fo:block> <xsl:apply-templates /> </fo:block> </xsl:template> 但我想在最内层添加一个额外的节点,以防出现特定的属性值。例如,如果元

在my xsl中,已经为para、graphic等元素定义了模板。示例如下:

    <xsl:template match="para">    
            <fo:block>
            <xsl:apply-templates />             
      </fo:block>
  </xsl:template>

但我想在最内层添加一个额外的节点,以防出现特定的属性值。例如,如果元素的属性值为changeStatus=new/changed,我需要在其他节点中添加'fo:changebarbegin'元素。xml示例:

    <para changeStatus="new">
This is a paragraph that has change bars applied to the whole paragraph. </para>

这是一个将更改栏应用于整个段落的段落。
输出应该是(这里fo:block节点来自xsl中的其他模板):


这是一个将更改栏应用于整个段落的段落。
我正在使用此代码,但在某些情况下,它是在外部级别添加节点,而在其他情况下,它是删除在其他模板中定义的节点(例如fo:block)

 <xsl:template match="*[@changeStatus='new' or @changeStatus='changed']">
         <fo:change-bar-begin change-bar-style="solid"/>

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

         <fo:change-bar-end/>
 </xsl:template>

这里,para只是一个示例,我需要这段代码来处理许多元素,所以使用调用模板不是一个选项。
请建议最好的方法。

每次选择一个节点进行转换时,将恰好有一个模板与之匹配并应用,除非所选模板可能指示其他模板应用于同一节点。因此,如果添加与已具有匹配模板的节点相匹配的模板,则会获得一个模板或另一个模板的效果,而不是两者的组合

现在,如果您想在现有模板生成的最外层元素周围放置
更改栏
,那么这是一回事,但是将
更改栏
放置在它们内部需要修改或克隆所有需要此类处理的现有模板。我强烈推荐“修改”选项,因为维护它会容易得多

例如,以模板匹配
para
元素为例。您可以这样修改它:

<xsl:template match="para">
  <fo:block>
    <xsl:apply-templates select="." mode="cb-begin-choice"/>
    <xsl:apply-templates />             
    <xsl:apply-templates select="." mode="cb-end-choice"/>
  </fo:block>
</xsl:template>

对于所有模板,您都可以通过以下方式支持:

<xsl:template match="*" mode="cb-begin-choice">
  <xsl:if test="@changeStatus='new' or @changeStatus='changed'">
    <fo:change-bar-begin change-bar-style="solid"/>
  </xsl:if>
</xsl:template>

<xsl:template match="*" mode="cb-end-choice">
  <xsl:if test="@changeStatus='new' or @changeStatus='changed'">
    <fo:change-bar-end/>
  </xsl:if>
</xsl:template>

将更改栏详细信息拉到这两个附加模板中,可以更轻松地进行这些更改,并使修改后的模板更清晰。它还为您提供了一个控制更改栏详细信息的位置,这样,如果您想要更改它们,您就可以在这两个模板中进行更改

 <xsl:template match="*[@changeStatus='new' or @changeStatus='changed']">
         <fo:change-bar-begin change-bar-style="solid"/>

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

         <fo:change-bar-end/>
 </xsl:template>

如果愿意,您可以在命名模板和
xsl:call template
上实现相同的功能,而不是在模式和
xsl:apply templates

上实现,每次选择一个节点进行转换时,都会匹配并应用一个模板,除非所选模板可能指示将其他模板应用于同一节点。因此,如果添加与已具有匹配模板的节点相匹配的模板,则会获得一个模板或另一个模板的效果,而不是两者的组合

现在,如果您想在现有模板生成的最外层元素周围放置
更改栏
,那么这是一回事,但是将
更改栏
放置在它们内部需要修改或克隆所有需要此类处理的现有模板。我强烈推荐“修改”选项,因为维护它会容易得多

例如,以模板匹配
para
元素为例。您可以这样修改它:

<xsl:template match="para">
  <fo:block>
    <xsl:apply-templates select="." mode="cb-begin-choice"/>
    <xsl:apply-templates />             
    <xsl:apply-templates select="." mode="cb-end-choice"/>
  </fo:block>
</xsl:template>

对于所有模板,您都可以通过以下方式支持:

<xsl:template match="*" mode="cb-begin-choice">
  <xsl:if test="@changeStatus='new' or @changeStatus='changed'">
    <fo:change-bar-begin change-bar-style="solid"/>
  </xsl:if>
</xsl:template>

<xsl:template match="*" mode="cb-end-choice">
  <xsl:if test="@changeStatus='new' or @changeStatus='changed'">
    <fo:change-bar-end/>
  </xsl:if>
</xsl:template>

将更改栏详细信息拉到这两个附加模板中,可以更轻松地进行这些更改,并使修改后的模板更清晰。它还为您提供了一个控制更改栏详细信息的位置,这样,如果您想要更改它们,您就可以在这两个模板中进行更改

 <xsl:template match="*[@changeStatus='new' or @changeStatus='changed']">
         <fo:change-bar-begin change-bar-style="solid"/>

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

         <fo:change-bar-end/>
 </xsl:template>

如果愿意,可以在命名模板和
xsl:call template
上实现相同的功能,而不是在模式和
xsl:apply templates

上实现,这并不容易,如果属性只是在其他内容之前添加内容,则可以将
更改为
,并添加与
@changeStatus[.=('new','changed')]
匹配的模板以输出,例如
。但是,如果需要让属性在不同的位置创建结果元素,则需要使用区分模式两次应用模板。这并不容易,如果属性只是在其他内容之前添加内容,则可以将
更改为
,并添加与
@changeStatus>匹配的模板[.=('new','changed')]
以输出,例如
。但是如果需要让属性在不同位置创建结果元素,则需要
应用模板两次,并使用区分模式。