我需要替换输入xml的多个元素的值。输入文件有大约 300 个元素,我需要替换其中大约 100 个元素。我以前使用过身份模板,但我认为这需要我编写 100 个不同的模板,每个模板用于替换单个元素值。我不太擅长xslts,所以,我的想法是对的,还是有更好的优雅方法?请指教。
编辑
这是示例输入 xml 的链接。
输出将具有几乎相同的结构,但某些元素的值不同。
好吧,我以前做过类似的事情,所以我很乐意分享......修改为您的示例,但不执行值映射,它执行名称映射。首先创建一个简单的映射文件,如下所示(注意:您需要命名空间才能正确执行此操作
<env:map xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<elem old="CardCode" new="CodeCardNEW"/>
<elem old="CardName" new="IAMNew"/>
</env:map>
然后一个模板将为您查找。可能有更好的方法来进行映射,我只是为了每个循环它们......钥匙会更好。但这能让你到达那里。
从您的文件输出与上面:
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<env:Body>
<GetByKeyResponse>
<BOM>
<BO>
<AdmInfo>
<Object>oBusinessPartners</Object>
</AdmInfo>
<BusinessPartners>
<row>
<CodeCardNEW>CR43WEB</CodeCardNEW>
<IAMNew>Zack Burns</IAMNew>
<CardType>cCustomer</CardType>
...
下面是 XSL:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:env="http://www.w3.org/2003/05/soap-envelope"
version="1.0">
<xsl:param name="map" select="document('map.xml')/env:map"></xsl:param>
<xsl:template match="text()" priority="1">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:variable name="newname">
<xsl:call-template name="namesub">
<xsl:with-param name="name" select="name()"/>
</xsl:call-template>
</xsl:variable>
<xsl:element name="{$newname}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template name="namesub">
<xsl:param name="name"/>
<xsl:variable name="newname">
<xsl:for-each select="$map/elem">
<xsl:choose>
<xsl:when test="@old = $name">
<xsl:value-of select="@new"/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:variable>
<xsl:choose>
<xsl:when test="string-length($newname) > 0">
<xsl:value-of select="$newname"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$name"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
只要您的名字匹配,您应该能够适应它......如果名称在 XML 的不同层次结构中相同,则需要执行更多工作。