How do I remove spaces in all attribute values using xslt?

女生的网名这么多〃 提交于 2019-12-19 04:09:52

问题


I want to remove spaces from all attributes in my xmls using xslt. I used strip-space, but that removes the spaces from nodes. My input xml is:

<OrderList>
<Order OrderDate="26-July" OrderNo="ORDER 12345"
 CustomertName="JOHN DOE" OrderKey="ORDKEY12345">
<ShipAddress AddressLine="ABC Colony" FirstName="John" LastName="Doe "/>
</Order>
</OrderList>

and the xsl I used to get rid of the spaces in the attributes like CustomertName="JOHN DOE" is:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/> 
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:apply-templates/>
<OrderList>
    <xsl:for-each select="OrderList/Order">
        <xsl:element name="Order">
            <xsl:copy-of select="@OrderDate"/>
            <xsl:copy-of select="@OrderNo"/>
            <xsl:copy-of select="@CustomertName"/>

            <!-- ShipAddress begins -->
            <xsl:element name="ShipAddress">                                           
                <xsl:copy-of select="ShipAddress/@AddressLine"/>
                <xsl:copy-of select="ShipAddress/@FirstName"/>
                <xsl:copy-of select="ShipAddress/@LastName"/>                       
            </xsl:element>
        </xsl:element>
    </xsl:for-each>             
</OrderList>
</xsl:template>
</xsl:stylesheet> 

But this leaves the input xml as it was. I want to remove the spaces from the attribute values at all levels.


回答1:


You can use the translate function, like so, although it would make sense to refactor this with a call template:

<xsl:attribute name="OrderDate">
    <xsl:value-of select="translate(@OrderDate, ' ','')"/>
</xsl:attribute>
<xsl:attribute name="OrderNo">
    <xsl:value-of select="translate(@CustomertName, ' ','')"/>
</xsl:attribute>
<xsl:attribute name="CustomertName">
    <xsl:value-of select="translate(@CustomertName, ' ','')"/>
</xsl:attribute>



回答2:


If you just want to removes spaces from the values of attributes, you could just create a template to match any attribute, and then use the translate function.

<xsl:template match="@*">
   <xsl:attribute name="{name()}">
      <xsl:value-of select="translate(., ' ', '')" />
   </xsl:attribute>
</xsl:template>

And if you want to filter out some attributes, you can create templates to match, and then ignore them. (XSLT will match the more specific template first)

<xsl:template match="Order/@OrderKey" />

You can also simplify you code somewhat by making use of the identity transform to cope existing nodes. Here is the full XSLT

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

   <xsl:template match="@*">
      <xsl:attribute name="{name()}">
         <xsl:value-of select="translate(., ' ', '')" />
      </xsl:attribute>
   </xsl:template>

   <xsl:template match="Order/@OrderKey" />

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

When applied to your sample XML, the following is ouptut

<OrderList>
  <Order OrderDate="26-July" OrderNo="ORDER12345" CustomertName="JOHNDOE">
    <ShipAddress AddressLine="ABCColony" FirstName="John" LastName="Doe"></ShipAddress>
  </Order>
</OrderList>

The advantage of this approach is that it will work with any XML document.

If you wanted to do this only for specific elements, try this XSLT instead which explicitly matches the attributes you want (and discards all others)

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

   <xsl:template match="Order/@OrderDate|Order/@OrderNo|Order/@CustomertName|ShipAddress/@AddressLine|ShipAddress/@FirstName|ShipAddress/@LastName">
      <xsl:attribute name="{name()}">
         <xsl:value-of select="translate(., ' ', '')"/>
      </xsl:attribute>
   </xsl:template>

   <xsl:template match="@*"/>

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

EDIT: If you wanted to remove only leading and trailing spaces, then 'normalize-space' is your friend.

<xsl:value-of select="normalize-space(.)" />

Do note this will remove excess spaces within the attribute though (that is to say double-spaces become single spaces between words).



来源:https://stackoverflow.com/questions/12054399/how-do-i-remove-spaces-in-all-attribute-values-using-xslt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!