简体   繁体   中英

XSL copy then replace attributes

INPUT.xml

 <human gender="male" nationality="american">
    <property>blank</property>
 </human>

(desired) OUTPUT.xml

 <human gender="male" nationality="american">
    <property>blank</property>
 </human>
 <person gender="female" nationality="british">
    <property>blank</property>
 </person>

Hi guys, the above is my desired transform. I have the following xsl so far:

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

But how i go about replacing the attribute values I tried using a xsl:choose but without luck

Your stylesheet was close, it just lacks a template matching those nodes that are not matched by your other template, so they do not get picked up by the built-in templates of XSLT .

For the transformation of the attributes I chose to introduce modes, so that some templates only match in the second case where you want to change the attribute values.

The following stylesheet

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="human">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
    <person>
        <!-- mode is used to separate this case from the other where things are copied unchanged -->
        <xsl:apply-templates select="node()|@*" mode="other" />
    </person>   
</xsl:template>

<!-- templates for normal mode -->

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

<!-- templates for "other" mode -->

<xsl:template match="@gender" mode="other">
    <xsl:attribute name="gender">
        <xsl:if test=". = 'male'">female</xsl:if>
        <xsl:if test=". = 'female'">male</xsl:if>
    </xsl:attribute>
</xsl:template>

<xsl:template match="@nationality" mode="other">
    <xsl:attribute name="nationality">
        <xsl:if test=". = 'american'">british</xsl:if>
        <xsl:if test=". = 'british'">american</xsl:if>
    </xsl:attribute>
</xsl:template>

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

</xsl:stylesheet>

when applied to this input:

<human gender="male" nationality="american">
    <property>blank</property>
</human>

gives the following result:

<?xml version="1.0" encoding="UTF-8"?>
<human gender="male" nationality="american">
    <property>blank</property>
</human>
<person gender="female" nationality="british">
    <property>blank</property>
</person>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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