0

我需要替换输入 xml 的多个元素的值。输入文件有大约 300 个元素,我需要替换其中大约 100 个元素。我以前使用过标识模板,但我认为这需要我编写 100 个不同的模板来替换单个元素值。我不太擅长 xslts,所以,我认为它是对的,还是有更好的优雅方法?请指教。

编辑

这是示例输入 xml 的链接

输出将具有几乎相同的结构,但某些元素的值不同。

4

1 回答 1

0

好吧,我之前做过类似的事情,所以我很乐意分享......修改为您的示例但不执行值映射,它执行名称映射。首先创建一个像这样的简单映射文件(注意:您需要命名空间才能正确执行此操作

    <env:map xmlns:env="http://www.w3.org/2003/05/soap-envelope">
        <elem old="CardCode" new="CodeCardNEW"/>
        <elem old="CardName" new="IAMNew"/>
    </env:map>

然后一个模板将为您提供查找。可能有更好的方法来进行映射,我只是 for-each 循环它们......一个键会更好。但这会让你到达那里。

上面的文件输出:

<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 的不同层次结构中相同,则需要做更多的工作。

于 2013-09-16T20:29:44.253 回答