2017-02-24 44 views
1

开始与该XML(在Access中导入):XSLT当属性是一个数字

<?xml version="1.0" encoding="UTF-8"?> 
<ITEM> 
    <PRODUCT_CODE TYPE="EPSON">V11H106040JA</PRODUCT_CODE> 
    <PRODUCT_CODE TYPE="EAN">8715946168340</PRODUCT_CODE> 
    <DESCRIPTION>EMP-73 VIDEOPROJECTOR</DESCRIPTION> 
    <QUANTITY TYPE="MINQTY" UNIT="PCE">20.0000000000</QUANTITY> 
    <QUANTITY TYPE="MAXQTY" UNIT="PCE">20.0000000000</QUANTITY> 
    <QUANTITY TYPE="MINORDQTY" UNIT="PCE">0</QUANTITY> 
    <PRICE TYPE="DIRECT">2000.0000</PRICE> 
    <PRICE TYPE="INDIRECT" /> 
    <PRICE TYPE="FINAL" /> 
    <CURRENCY>EUR</CURRENCY> 
    <CATEGORY TYPE="ONE1">51</CATEGORY> 
</ITEM> 

这XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 
    <xsl:template match="ITEM"> 
    <xsl:copy> 
       <xsl:for-each select="*"> 
        <xsl:if test="@*"> 
         <xsl:element name="{@*}"><xsl:value-of select="."/> 
         </xsl:element> 
        </xsl:if>   
       </xsl:for-each> 
     <xsl:copy-of select="*[not(@*)]"/>  
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

我得到这个:

<?xml version="1.0" encoding="UTF-8"?> 
<ITEM> 
    <EPSON>V11H106040JA</EPSON> 
    <EAN>8715946168340</EAN> 
    <MINQTY>20.0000000000</MINQTY> 
    <MAXQTY>20.0000000000</MAXQTY> 
    <MINORDQTY>0</MINORDQTY> 
    <DIRECT>2000.0000</DIRECT> 
    <INDIRECT/> 
    <FINAL/> 
    <ONE1>51</ONE1> 
    <DESCRIPTION>EMP-73 VIDEOPROJECTOR</DESCRIPTION> 
    <CURRENCY>EUR</CURRENCY> 
</ITEM> 

但是,如果我在第13行更改XML如下

<CATEGORY TYPE="1">51</CATEGORY> 

(TYPE属性成为数字)我得到一个转换错误“无法应用样式表”,为什么?!? 我应该如何更改我的XSLT以获得以下结果?

<CATEGORY-1>51</CATEGORY-1> 

回答

3

您正在使属性值成为新元素的名称,但XML元素名称不能以数字开头。所以你必须检测到这一点,并像前面提到的那样,在前面的元素名称前加上。

试试这个:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output indent="yes"/> 
<xsl:strip-space elements="*"/> 
<xsl:template match="ITEM"> 
    <xsl:copy> 
     <xsl:for-each select="*"> 
      <xsl:if test="@*"> 
       <xsl:choose> 
        <xsl:when test="number(substring(@*[1], 1, 1)+1)"> 
         <!-- when attribute value starts with number --> 
         <xsl:element name="{concat(name(.), '-', @*)}"> 
          <xsl:value-of select="."/> 
         </xsl:element> 
        </xsl:when> 
        <xsl:otherwise> 
         <xsl:element name="{@*}"> 
          <xsl:value-of select="."/> 
         </xsl:element> 
        </xsl:otherwise> 
       </xsl:choose> 
      </xsl:if>   
     </xsl:for-each> 
     <xsl:copy-of select="*[not(@*)]"/>  
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

小提琴:http://xsltransform.net/94AbWBW/1