繁体   English   中英

使用 XSLT 替换保留 XML 结构的节点中的值

[英]Replace value in a node retaining the XML Structure using XSLT

我有一个需求,我需要根据具有不同值的属性替换节点的值,同时保留原始 XML 结构。 基本上,当在原始 XML 中遇到特定属性时,我只需要通过替换某些值来复制整个 XML。

下面是转换前和转换后的示例 XML。

原始 XML:

<root>
    <body>
        <node_level1>
            <node_level2>
                <node_level3>
                    <value animal="cat">Munchkin</value>
                </node_level3>
                <node_level3>
                    <value animal="cat">Turkish Angora</value>
                </node_level3>
                <node_level3>
                    <value animal="cat">La Perm</value>
                </node_level3>
            </node_level2>
            <node_level2>
                <node_level3>
                    <node_level4>
                        <value animal="dog">Siberian Husky</value>
                    </node_level4>
                    <node_level4>
                        <value animal="dog">Pug</value>
                    </node_level4>
                    <node_level4>
                        <value animal="dog">Beagle</value>
                    </node_level4>
                </node_level3>
            </node_level2>
        </node_level1>
    </body>
</root>

使用 XSLT 转换数据后,我需要如下 XML:

<root>
    <body>
        <node_level1>
            <node_level2>
                <node_level3>
                    <value animal="cat">Cat Family</value>
                </node_level3>
                <node_level3>
                    <value animal="cat">Cat Family</value>
                </node_level3>
                <node_level3>
                    <value animal="cat">Cat Family</value>
                </node_level3>
            </node_level2>
            <node_level2>
                <node_level3>
                    <node_level4>
                        <value animal="dog">Dog Family</value>
                    </node_level4>
                    <node_level4>
                        <value animal="dog">Dog Family</value>
                    </node_level4>
                    <node_level4>
                        <value animal="dog">Dog Family</value>
                    </node_level4>
                </node_level3>
            </node_level2>
        </node_level1>
    </body>
</root>

这是适用于指定属性的代码,我需要对其进行概括。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="xsl" version="2.0">
    <xsl:template match="/">
        <root>
            <xsl:for-each select="//*[value[@animal = 'cat']]">
                <xsl:copy>
                    <xsl:value-of select="@*"/>
                    <xsl:value-of select="'Cat Family'"/>
                </xsl:copy>
            </xsl:for-each>
        </root>
    </xsl:template>
</xsl:stylesheet>

这是一项非常简单的任务,您需要使用身份模板来复制所有 xml 节点,因为它是:

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

然后您可以根据您的要求使用单独的value元素模板:

<xsl:template match="value">
    <xsl:choose>
        <xsl:when test="@animal = 'cat'">
            <value animal="cat">Cat Family</value>
        </xsl:when>
        <xsl:when test="@animal = 'dog'">
            <value animal="dog">Dog Family</value>
        </xsl:when>
    </xsl:choose>
</xsl:template>

最终的 XSL 文件是:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="xsl" version="2.0">

    <!-- indent elements to see properly -->
    <xsl:output indent="yes"/>

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

    <xsl:template match="value">
        <xsl:choose>
            <xsl:when test="@animal = 'cat'">
                <value animal="cat">Cat Family</value>
            </xsl:when>
            <xsl:when test="@animal = 'dog'">
                <value animal="dog">Dog Family</value>
            </xsl:when>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

在 XSLT 3 中,您可以使用xsl:mode on-no-match="shallow-copy"作为默认处理声明身份转换,然后匹配value[@animal]

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:template match="value[@animal]">
      <xsl:copy>
          <xsl:apply-templates select="@*"/>
          <xsl:value-of select="@animal || ' family'"/>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/94Acsmj

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM