Xslt根据条件规则引用另一个元素来更改元素值
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Xslt根据条件规则引用另一个元素来更改元素值相关的知识,希望对你有一定的参考价值。
我有这样的xml:
<?xml version="1.0" encoding="utf-8"?>
<FormDataRequest>
<Name>Bob</Name>
<sn>Ross</sn>
<company>MS Paint</company>
<department>Paint bucket</department>
</FormDataRequest>
我应该根据文本条件改变<company>
和<department>
的值。
我试过这个xslt:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="FormDataRequest" />
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="FormDataRequest">
<xsl:variable name="realcompany">
<xsl:choose>
<xsl:when test="./department/text() = 'Paint bucket'">
<xsl:text>Co company 1</xsl:text>
</xsl:when>
<xsl:when test="./department/text() = 'Paint brush'">
<xsl:text>Co company 2</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:variable name="realdepartment">
<xsl:choose>
<xsl:when test="./department/text() = 'Paint bucket'">
<xsl:text>Bucket department</xsl:text>
</xsl:when>
<xsl:when test="./department/text() = '´Paint brush'">
<xsl:text>Brush department</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:variable>
<FormDataRequest>
<xsl:apply-templates select="@*|node()" />
<company>
<xsl:value-of select="$realcompany"/>
</company>
<department>
<xsl:value-of select="$realdepartment"/>
</department>
</FormDataRequest>
</xsl:template>
</xsl:stylesheet>
输出:
<FormDataRequest>
<Name>Bob</Name>
<sn>Ross</sn>
<company>MS Paint</company>
<department>Paint bucket</department>
<company>Co company 1</company>
<department>Bucket department</department>
</FormDataRequest>
我不想保留旧公司和部门的价值观。
所以out put应该看起来像这样:
<?xml version="1.0" encoding="utf-8"?>
<FormDataRequest>
<Name>Bob</Name>
<sn>Ross</sn>
<company>Co company 1</company>
<department>Bucket department</department>
</FormDataRequest>
答案
使用您的XSL代码非常接近,但更容易和可读的方法是创建替换动态模板,这将帮助您更改有关变量条件的公司和部门块值,请参阅下面的XSL:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<!--declare condition for company block-->
<xsl:variable name="realcompany">
<xsl:choose>
<xsl:when test="//department = 'Paint bucket'">
<xsl:value-of select="'Co company 1'"/>
</xsl:when>
<xsl:when test="//department = 'Paint brush'">
<xsl:value-of select="'Co company 2'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//company"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!--declare condition for department block-->
<xsl:variable name="realdepartment">
<xsl:choose>
<xsl:when test="//department = 'Paint bucket'">
<xsl:value-of select="'Bucket department'"/>
</xsl:when>
<xsl:when test="//department = 'Paint brush'">
<xsl:value-of select="'Brush department'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//department"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!--dynamic template for replacing current value to condition value-->
<xsl:template name="value-to-replace">
<xsl:param name="param.str"/>
<xsl:param name="param.target"/>
<xsl:param name="param.replacement"/>
<xsl:choose>
<xsl:when test="contains($param.str, $param.target)">
<xsl:value-of select="concat(substring-before($param.str, $param.target), $param.replacement, substring-after($param.str, $param.target))"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$param.str"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--replace value in company block with realcompany variable condition-->
<xsl:template match="company[parent::FormDataRequest]">
<xsl:element name="{name()}">
<xsl:call-template name="value-to-replace">
<xsl:with-param name="param.str" select="."/>
<xsl:with-param name="param.target" select="//company"/>
<xsl:with-param name="param.replacement" select="$realcompany"/>
</xsl:call-template>
</xsl:element>
</xsl:template>
<!--replace value in department block with realdepartment variable condition-->
<xsl:template match="department[parent::FormDataRequest]">
<xsl:element name="{name()}">
<xsl:call-template name="value-to-replace">
<xsl:with-param name="param.str" select="."/>
<xsl:with-param name="param.target" select="//company"/>
<xsl:with-param name="param.replacement" select="$realdepartment"/>
</xsl:call-template>
</xsl:element>
</xsl:template>
<!--copy all nodes-->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
结果将如预期:
<FormDataRequest>
<Name>Bob</Name>
<sn>Ross</sn>
<company>Co company 1</company>
<department>Paint bucket</department>
</FormDataRequest>
另一答案
那么,你在<xsl:apply-templates select="@*|node()" />
结果元素中的FormDataRequest
处理现有的子节点,并且你使用身份转换来复制它们。如果您想要排除这两个元素,建议对现有代码进行一次更改,请将<xsl:apply-templates select="@*|node()" />
更改为<xsl:apply-templates select="@*|node() except (company, department)" />
。
以上是关于Xslt根据条件规则引用另一个元素来更改元素值的主要内容,如果未能解决你的问题,请参考以下文章
XSLT 2.0:根据 for-each -group 的当前索引评估和修改元素值