XSLT Remove leading and trailing whitespace of all attributes

33,492

Solution 1

normalize-space() will not only remove leading and trailing whitespace, but it will also install a single space character in place of any sequence of consecutive whitespace characters.

A regular expression can be used to handle just leading and trailing whitespace:

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

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

  <xsl:template match="@*">
    <xsl:attribute name="{local-name()}" namespace="{namespace-uri()}">
      <xsl:value-of select="replace(., '^\s+|\s+$', '')"/>
    </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

Solution 2

This should do it:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

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

  <xsl:template match="@*">
    <xsl:attribute name="{name()}">
      <xsl:value-of select="normalize-space()"/>
    </xsl:attribute>
  </xsl:template>
</xsl:stylesheet>

This is also XSLT 1.0 compatible.

When run on your sample input, the result is:

<node id="DSN">
  <event id="2190">
    <attribute key="Teardown" />
    <attribute key="Resource" />
  </event>
</node>

One thing to note here is that normalize-space() will turn any whitespace within the attribute values into single spaces, so this:

<element attr="   this    is an
                   attribute   " />

Would be changed to this:

<element attr="this is an attribute" />

If you need to keep whitespace within the value as-is, then please see Gunther's answer.

Share:
33,492
Admin
Author by

Admin

Updated on December 31, 2020

Comments

  • Admin
    Admin over 3 years

    How can I create an identical XML sheet, but with the leading and trailing whitespaces of each attribute removed? (using XSLT 2.0)

    Go from this:

    <node id="DSN ">
        <event id=" 2190 ">
            <attribute key=" Teardown"/>
            <attribute key="Resource "/>
        </event>
    </node>
    

    To this:

    <node id="DSN">
        <event id="2190">
            <attribute key="Teardown"/>
            <attribute key="Resource"/>
        </event>
    </node>
    

    I suppose I'd prefer to use the normalize-space() function, but whatever works.