3

xslt を使用して、xml 内のすべての属性からスペースを削除したいと考えています。を使用strip-spaceしましたが、ノードからスペースが削除されます。私の入力xmlは次のとおりです。

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

そして、次のような属性のスペースを取り除くために使用したxslCustomertName="JOHN DOE"は次のとおりです。

<?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> 

しかし、これは入力xmlをそのまま残します。すべてのレベルで属性値からスペースを削除したいと考えています。

4

2 に答える 2

10

このように翻訳関数を使用できますが、呼び出しテンプレートを使用してこれをリファクタリングすることは理にかなっています。

<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>
于 2012-08-21T12:12:27.477 に答える
7

属性の値からスペースを削除したい場合は、任意の属性に一致するテンプレートを作成してから、翻訳機能を使用できます。

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

また、一部の属性を除外したい場合は、一致するテンプレートを作成して、それらを無視することができます。(XSLT は、より具体的なテンプレートに最初に一致します)

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

恒等変換を利用して既存のノードに対処することで、コードをいくらか単純化することもできます。ここに完全な 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>

サンプル XML に適用すると、次の出力になります。

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

このアプローチの利点は、あらゆる XML ドキュメントで機能することです。

特定の要素に対してのみこれを行いたい場合は、代わりにこの XSLT を試してください。これは、必要な属性に明示的に一致します (そして、他のすべてを破棄します)。

<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>

編集:先頭と末尾のスペースのみを削除したい場合は、「normalize-space」が役に立ちます。

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

ただし、これにより属性内の余分なスペースが削除されることに注意してください (つまり、ダブルスペースは単語間のシングルスペースになります)。

于 2012-08-21T12:13:20.983 に答える