Question

I'm kinda stuck on a transformation i'd like to make on a xml file.

Basically i'm trying to copy all the xml but change some tags which only begins like this

XML code :

<test alt="foo" title="bar"/>

What i'd like to get after passing the xsl :

<test alt="foo"/>

Or

<change alt="foo" title=""/>

Thing is, sometimes i got tag with a lot of attributes, so i dont want to make a template match and then change every attributes manually.

Actually i'm doing this :

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

<xsl:template match="test/@title">
    <xsl:attribute name="title">
        <xsl:value-of select=""/>
    </xsl:attribute>
</xsl:template>

But it doesnt change the content of title in the output.

Was it helpful?

Solution

For all such tasks you should start with the identity transformation template

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

and then add templates for nodes that need special treatment, for instance

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

<xsl:template match="test/@title"/>

would copy everything unchanged but would delete all title attributes of test elements.

Or

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

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

<xsl:template match="test/@title">
    <xsl:attribute name="title"/>
</xsl:template>

should implement your second requirement. If you still have problems then post minimal but complete samples allowing us to reproduce the problem.

OTHER TIPS

To remove any attributes save for alt, use an identity transform with an exception:

Stylesheet (remove other attributes)

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

    <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

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

    <xsl:template match="@*[name() != 'alt']"/>

</xsl:stylesheet>

Output

<?xml version="1.0" encoding="utf-8"?>
<test alt="foo"/>

Or else, to set the value of all attributes except that of alt to "", use:

Stylesheet (make other attributes empty)

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

    <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

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

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

    <xsl:template match="@*[name() != 'alt']">
        <xsl:attribute name="{name()}"/>
    </xsl:template>

</xsl:stylesheet>

Output

<?xml version="1.0" encoding="utf-8"?>
<change alt="foo" title=""/>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top