bohdan
bohdan

Reputation: 23

xml attribute replacement with xslt

How can i replace an attribute in xml using xsl transformation, depending on its value. For example, if there is such xml

<Text Style='style1'>
...
</Text>

transform it to

<Text Font='Arial' Bold='true' Color='Red'>
...
</Text>

For Style='style2' set another attributes and values, for example Font='Sans' Italic='true'.

Upvotes: 2

Views: 1239

Answers (2)

Bronumski
Bronumski

Reputation: 14272

You will need to have some kind of rule that you use to convert the style from one to the other. Making the assumption you are inputting html you will need something like.

  <xsl:template match="@* | node()">
    <xsl:choose>
      <xsl:when test="local-name() = 'Style'">
        <xsl:apply-templates select="." mode="Style" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="@Style" mode="Style">
    <xsl:choose>
      <xsl:when test="node() = 'style1'">
        <xsl:attribute name="Font">Arial</xsl:attribute>
        <xsl:attribute name="Bold">true</xsl:attribute>
        <xsl:attribute name="Color">Red</xsl:attribute>
      </xsl:when>
      <xsl:when test="node() = 'style2'">
        <xsl:attribute name="Font">Sans</xsl:attribute>
        <xsl:attribute name="Bold">true</xsl:attribute>
      </xsl:when>
    </xsl:choose>
  </xsl:template>

Upvotes: 0

user357812
user357812

Reputation:

One posible way: ussing attribute sets. This stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:attribute-set name="style1">
        <xsl:attribute name="Font">Arial</xsl:attribute>
        <xsl:attribute name="Bold">true</xsl:attribute>
        <xsl:attribute name="Color">Red</xsl:attribute>
    </xsl:attribute-set>
    <xsl:attribute-set name="style2">
        <xsl:attribute name="Font">Sans</xsl:attribute>
        <xsl:attribute name="Italic">true</xsl:attribute>
    </xsl:attribute-set>
    <xsl:template match="Text[@Style='style1']">
        <xsl:copy use-attribute-sets="style1">
            <xsl:copy-of select="@*[name()!='Style']"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="Text[@Style='style2']">
        <xsl:copy use-attribute-sets="style2">
            <xsl:copy-of select="@*[name()!='Style']"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

With this input:

<root>
    <Text Style='style1'></Text>
    <Text Style='style2'></Text>
</root>

Output:

<Text Font="Arial" Bold="true" Color="Red"></Text>
<Text Font="Sans" Italic="true"></Text>

Other way: inline "attribute sets". This stylesheet:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my"
 exclude-result-prefixes="my">
    <xsl:output indent="yes"/>
    <my:style1 Font="Arial" Bold="true" Color="Red"/>
    <my:style2 Font="Sans" Italic="true"/>
    <xsl:template match="Text[@Style]">
        <xsl:copy>
            <xsl:copy-of select="document('')/*/my:*
                                    [local-name()=current()/@Style]/@*"/>
            <xsl:copy-of select="@*[name()!='Style']"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Upvotes: 2

Related Questions