2014-09-30 59 views
2

我是XSLT和XML的新手。我一直在通過教程和stackoverflow的例子,並學習了很多新的東西。XML到CSV應用XSLT(格式問題,邏輯錯誤)

當前我正在嘗試將XSLT應用於XML文件以將其轉換爲CSV。我想要實現的是,我在XML文件中提供了一些我想要提取的信息。 CSV文件默認會有一些信息,我將在XSLT中傳遞這些信息。

另外我也使用了基本的XSLT語法,我很快就學會了,我相信這是最糟糕的方式。我會很感激所有的幫助,如果有人能指導我如何使這個解決方案更好。是

我遇到的問題如下:

  1. 的信息沒有得到正確的格式,它得到印上一個新的生產線,這是我不想除非我指定一個新行。此外,如果我不縮進XSLT文件,那麼信息可以保持單一,但代碼看起來很亂,我相信有一些簡單的方法來做到這一點。

  2. 每個人都有一些許可證,我想在for-each循環內讀取許可證,但我很困惑如何做到這一點。就好像這個人沒有一些許可證,那麼默認情況下,我希望它是空白的。目前在這個例子中我使用了5個狀態。

這是我用來測試的xml文件。

<?xml version="1.0" encoding="UTF-8"?> 
<People> 
<Person> 
    <required-tag1>some-information</required-tag1> 
    <required-tag2>some-information</required-tag2> 
    <first-name>Mike</first-name> 
    <last-name>Hewitt</last-name> 
    <licenses> 
     <license> 
      <state xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">IL</state> 
     </license> 
    </licenses> 
</Person> 
<Person> 
    <required-tag1>some-information</required-tag1> 
    <required-tag2>some-information</required-tag2> 
    <first-name>John</first-name> 
    <last-name>Jhonny</last-name> 
    <licenses> 
     <license> 
      <state xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">NY</state> 
     </license> 
    </licenses> 
</Person> 
<Person> 
    <required-tag1>some-information</required-tag1> 
    <required-tag2>some-information</required-tag2> 
    <first-name>Xmen</first-name> 
    <last-name>Bat</last-name> 
    <licenses> 
     <license> 
      <state xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AK</state> 
     </license> 
     <license> 
      <state xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">CA</state> 
     </license> 
     <license> 
      <state xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">IL</state> 
     </license> 
     <license> 
      <state xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">NY</state> 
     </license> 
     <license> 
      <state xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">TX</state> 
     </license> 
    </licenses> 
</Person> 
</People> 

我寫的XSLT如下:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:csv="csv:csv" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output encoding="UTF-8" method="text"/> 
<xsl:template match="/People">First Name,Last Name,AK,CA,IL,NY,TX,default value1,required-tag1,required-tag2,default value2,default value3 
    <xsl:for-each select="Person"> 
     <xsl:value-of select="first-name"/>, <xsl:value-of select="last-name"/>,<xsl:choose> 
    <xsl:when test="licenses/license/state='AK'"> 
     <xsl:value-of select="licenses/license/state"/>, 
    </xsl:when> 
    <xsl:otherwise>NA, 
    </xsl:otherwise></xsl:choose><xsl:choose> 
    <xsl:when test="licenses/license/state='CA'"> 
     <xsl:value-of select="licenses/license/state"/>, 
    </xsl:when> 
    <xsl:otherwise>NA, 
    </xsl:otherwise></xsl:choose><xsl:choose> 
    <xsl:when test="licenses/license/state='IL'"> 
     <xsl:value-of select="licenses/license/state"/>, 
    </xsl:when> 
    <xsl:otherwise>NA, 
    </xsl:otherwise></xsl:choose><xsl:choose> 
    <xsl:when test="licenses/license/state='NY'"> 
     <xsl:value-of select="licenses/license/state"/>, 
    </xsl:when> 
    <xsl:otherwise>NA, 
    </xsl:otherwise></xsl:choose><xsl:choose> 
    <xsl:when test="licenses/license/state='TX'"> 
     <xsl:value-of select="licenses/license/state"/>, 
    </xsl:when> 
    <xsl:otherwise>NA, 
    </xsl:otherwise></xsl:choose>DEFAULT VALUE1,<xsl:value-of select="required-tag1"/>,<xsl:value-of select="required-tag2"/>,DEFAULT VALUE2,DEFAULT VALUE3<xsl:text>&#xa;</xsl:text> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

我嘗試使用的for-each中的for-each循環牌照但執行5次對所有許可證,如何循環執行條件以測試許可證狀態5次並根據默認保持格式正確。

這是我想輸出是:

First Name,Last Name,AK,CA,IL,NY,TX,default value1,required-tag1,required-tag2,default value2,default value3 
Mike, Hewitt,NA,NA,IL,NA,NA,DEFAULT VALUE1,some-information,some-information,DEFAULT VALUE2,DEFAULT VALUE3 
John, Jhonny,NA,NA,NA,NY,NA,DEFAULT VALUE1,some-information,some-information,DEFAULT VALUE2,DEFAULT VALUE3 
Xmen, Bat,AK,CA,IL,NY,TX,DEFAULT VALUE1,some-information,some-information,DEFAULT VALUE2,DEFAULT VALUE3 

我使用XSLT 1.0版本。

謝謝你的幫助。

+0

作爲參考,類似的問題已被問到這裏:http://stackoverflow.com/questions/365312/xml-to-csv-using-xslt你可能會發現那裏幾個有用的想法。 – Tomalak 2014-09-30 20:52:25

回答

3

對於新生產線的問題,考慮你如何目前正在寫NA作爲一個例子現在

<xsl:otherwise>NA, 
</xsl:otherwise> 

,如果你有就這...

<xsl:otherwise> 
</xsl:otherwise> 

然後XSLT不會輸出一條新線路。在xsl:otherwise下有一個文本節點,但是它只是一個空白節點,所以它被忽略。但是,只要向其中添加普通文本(如NA),XSLT就會認爲所有文本都很重要,並輸出它,包括新行。它不規範任何空間。

的解決方案是包裝所有這樣的文本在xsl:text

<xsl:otherwise> 
    <xsl:text>NA</xsl:text> 
</xsl:otherwise> 

至於你的邏輯問題,你現在正在做這個檢查的狀態

<xsl:when test="licenses/license/state='IL'"> 
    <xsl:value-of select="licenses/license/state"/>, 
</xsl:when> 

但有細微的差別在每個陳述中使用licenses/license/state之間。在xsl:when中,您詢問「是否有此狀態的許可證」,但在您的xsl:value-of中,它將獲得列表中的第一個狀態!現在

,你可以寫這個

<xsl:when test="licenses/license/state='IL'"> 
    <xsl:value-of select="licenses/license[state='IL']/state"/> 
    <xsl:text>,</xsl:text> 
</xsl:when> 

但是,這是相當多餘。最好將其簡化爲這個

<xsl:when test="licenses/license/state='IL'"> 
    <xsl:text>IL,</xsl:text> 
</xsl:when> 

還值得一提的,你顯然有很多重複的代碼,所以你可以通過使用一個命名模板中刪除一些這方面。

試試這個XSLT作爲一個例子

<xsl:stylesheet version="1.0" xmlns:csv="csv:csv" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output encoding="UTF-8" method="text"/> 

<xsl:template match="/People"> 
    <xsl:text>First Name,Last Name,AK,CA,IL,NY,TX,default value1,required-tag1,required-tag2,default value2,default value3</xsl:text> 
    <xsl:text>&#xa;</xsl:text> 
    <xsl:for-each select="Person"> 
     <xsl:value-of select="first-name"/> 
     <xsl:text>, </xsl:text> 
     <xsl:value-of select="last-name"/> 
     <xsl:text>, </xsl:text> 
     <xsl:call-template name="state"> 
      <xsl:with-param name="stateCode" select="'AK'" /> 
     </xsl:call-template> 
     <xsl:call-template name="state"> 
      <xsl:with-param name="stateCode" select="'CA'" /> 
     </xsl:call-template> 
     <xsl:call-template name="state"> 
      <xsl:with-param name="stateCode" select="'IL'" /> 
     </xsl:call-template> 
     <xsl:call-template name="state"> 
      <xsl:with-param name="stateCode" select="'NY'" /> 
     </xsl:call-template> 
     <xsl:call-template name="state"> 
      <xsl:with-param name="stateCode" select="'TX'" /> 
     </xsl:call-template> 
     <xsl:text>DEFAULT VALUE1,</xsl:text> 
     <xsl:value-of select="required-tag1"/> 
     <xsl:text>,</xsl:text> 
     <xsl:value-of select="required-tag2"/> 
     <xsl:text>,DEFAULT VALUE2,DEFAULT VALUE3</xsl:text> 
     <xsl:text>&#xa;</xsl:text> 
    </xsl:for-each> 
</xsl:template> 

<xsl:template name="state"> 
    <xsl:param name="stateCode" /> 
    <xsl:choose> 
     <xsl:when test="licenses/license[state=$stateCode]"> 
     <xsl:value-of select="$stateCode"/> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:text>NA</xsl:text> 
     </xsl:otherwise> 
    </xsl:choose> 
    <xsl:text>,</xsl:text> 
</xsl:template> 
</xsl:stylesheet> 

這還是相當反覆,隨着xsl:call-template的重複使用。如果您只想要5個固定狀態,則可以將這些狀態置於外部XML文檔中,並作爲示例進行循環。這將是另一個問題,雖然.....

+0

非常感謝您提供了這樣一個簡單易懂的描述性答案。我剛剛在這個解決方案中學到了很多東西。 – Aniks 2014-09-30 21:23:28