3

我想使用 xslt 从我的 xmls 中的所有属性中删除空格。我用过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

您可以像这样使用 translate 函数,尽管使用调用模板重构它是有意义的:

<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

如果您只想从属性值中删除空格,您可以创建一个模板来匹配任何属性,然后使用 translate 函数。

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

编辑:如果您只想删除前导和尾随空格,那么“规范化空间”是您的朋友。

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

请注意,这将删除属性中多余的空格(也就是说,双空格变成单词之间的单空格)。

于 2012-08-21T12:13:20.983 回答