Xml 如何在最内层添加新节点
在my xsl中,已经为para、graphic等元素定义了模板。示例如下:Xml 如何在最内层添加新节点,xml,xslt,Xml,Xslt,在my xsl中,已经为para、graphic等元素定义了模板。示例如下: <xsl:template match="para"> <fo:block> <xsl:apply-templates /> </fo:block> </xsl:template> 但我想在最内层添加一个额外的节点,以防出现特定的属性值。例如,如果元
<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')]
以输出,例如
。但是如果需要让属性在不同位置创建结果元素,则需要应用模板两次,并使用区分模式。