I am a XSLT newbie and have a simple task:
Suppose I have the following XML:
<Element1> <Element2 attr1="1"/> &l开发者_如何学JAVAt;/Element1> <Element1 attr1="2"/> <Element1> <Element2 attr1="2"/> </Element1>
I want to transform the XML to the same XML with one change: All attributes named "attr1" no matter where they are have to be transformed so that for example "1" will be "A" and "2" will be "X", i. e. to
<Element1> <Element2 attr1="A"/> </Element1> <Element1 attr1="X"/> <Element1> <Element2 attr1="X"/> </Element1>
How can I achieve this? Thanks in advance!
You can define characters to replace and replacing chars, then use translate
.
You can use this XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="in">12</xsl:variable>
<xsl:variable name="out">AX</xsl:variable>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@attr1">
<xsl:attribute name="attr1">
<xsl:value-of select="translate(., $in, $out)"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Another way:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@attr1">
<xsl:choose>
<xsl:when test=". = '1'">
<xsl:attribute name="attr1">
<xsl:text>A</xsl:text>
</xsl:attribute>
</xsl:when>
<xsl:when test=". = '2'">
<xsl:attribute name="attr1">
<xsl:text>X</xsl:text>
</xsl:attribute>
</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
<xsl:template match="@attr1">
will match all attributes attr1
, then using xsl:choose
you creates appropriate value for this attribute.
You didn't say what happens when @attr=3 for example so there is an otherwise clause to just copy the value if it is not one of the selected.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@attr1">
<xsl:attribute name="attr1">
<xsl:choose>
<xsl:when test=". = 1">
<xsl:text>A</xsl:text>
</xsl:when>
<xsl:when test=". = 2">
<xsl:text>X</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="." />
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Another way, using document
function:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:l="local"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@attr1">
<xsl:attribute name="attr1">
<xsl:value-of select="document('')//l:item[l:in = current()]/l:out"/>
</xsl:attribute>
</xsl:template>
<xml xmlns="local">
<item>
<in>1</in>
<out>A</out>
</item>
<item>
<in>2</in>
<out>X</out>
</item>
</xml>
</xsl:stylesheet>
xslt 2 version below works:
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@attr1[.='1']">
<xsl:attribute name="attr1">
<xsl:value-of select="replace(.,'1','A')"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="@attr1[.='2']">
<xsl:attribute name="attr1">
<xsl:value-of select="replace(.,'2','X')"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
精彩评论