2017-02-24 73 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