2017-06-14 49 views
0

我試圖首先實現一個簡單的轉換,但是我嘗試過的任何操作都失敗了。 XML由固定長度記錄生成並具有以下格式。使用XSLT縱向化XML

<?xml version="1.0" encoding="UTF-8"?> 
<record> 
    <no_of_records>30</no_of_records> 
    <cust_lastname_1>Smith</cust_lastname_1> 
    <cust_name_1>John</cust_name_1> 
    <cust_id_1>X45</cust_id_1> 
    <cust_lastname_2>George</cust_lastname_2> 
    <cust_name_2>Michael</cust_name_2> 
    <cust_id_2>X76</cust_id_2> 
    <cust_lastname_3>Ria</cust_lastname_3> 
    <cust_name_3>Chris</cust_name_3> 
    <cust_id_3>C87</cust_id_3> 
    ... 
</record> 

的no_of_records表示許多_X後綴元素如何包含每個記錄和由於其修復長度原點具有定義的最大值。 我想將它轉換爲「垂直化」的形式,更接近於下面的內容。

<record> 
    <customer num="1"> 
     <lastname>Smith</lastname> 
     <name>John</name> 
     <id>X45</id> 
    </customer> 
    <customer num="2"> 
     <lastname>George</lastname> 
     <name>Michael</name> 
     <id>X76</id> 
    </customer> 
    <customer num="3"> 
     <lastname>Ria</lastname> 
     <name>Chris</name> 
     <id>C87</id> 
     ... 
    </customer>  
</record> 

任何幫助將不勝感激。

+0

您可以使用XSLT 2.0嗎? –

+0

您的輸入XML格式錯誤。它有開始標籤,你似乎想要結束標籤,即使如此,並非所有結束標籤都與相應的開放標籤匹配。 –

+0

既然你說這個XML是從一個固定長度的記錄生成的,是否有機會直接從那個記錄生成你想要的XML表單?或者,最初的XML生成是否可以生成一個可以更容易地轉換爲所需輸出的表單,以及作爲輸入呈現在問題中的表單? –

回答

0

在XSLT 2.0,你要像

<xsl:for-each-group select="*" group-starting-with="*[starts-with(local-name(), 'cust_lastname']"> 
    <customer num="{position()}"> 
    <xsl:apply-templates select="current-group()"/> 
    </customer> 
</xsl:for-each-group> 

.... 

<xsl:template match="*[starts-with(local-name(), 'cust')]"> 
    <xsl:element name="{replace(local-name(), 'cust_(.*?)_[0-9]+', '$1')}"> 
    <xsl:value-of select="."/> 
    </xsl:element> 
</xsl:template> 
0

從@邁克爾凱解決方案的工作很好。謝謝 !

XML

<?xml version="1.0" encoding="UTF-8"?> 
<record> 
    <no_of_records>3</no_of_records> 
    <cust_lastname_1>Smith</cust_lastname_1> 
    <cust_name_1>John</cust_name_1> 
    <cust_id_1>X45</cust_id_1> 
    <cust_lastname_2>George</cust_lastname_2> 
    <cust_name_2>Michael</cust_name_2> 
    <cust_id_2>X76</cust_id_2> 
    <cust_lastname_3>Ria</cust_lastname_3> 
    <cust_name_3>Chris</cust_name_3> 
    <cust_id_3>C87</cust_id_3> 
</record> 

XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 
    <xsl:template match="record"> 
    <records> 
     <xsl:for-each-group select="*[starts-with(local-name(), 'cust_')]" 
     group-starting-with="*[starts-with(local-name(), 'cust_lastname')]"> 
     <customer num="{position()}"> 
      <xsl:apply-templates select="current-group()"/> 
     </customer> 
     </xsl:for-each-group> 
    </records> 
    </xsl:template>  
    <xsl:template match="*[starts-with(local-name(), 'cust')]"> 
     <xsl:element name="{replace(local-name(), 'cust_(.*?)_[0-9]+', '$1')}"> 
     <xsl:value-of select="."/> 
     </xsl:element> 
    </xsl:template>  
</xsl:stylesheet> 

結果

<?xml version="1.0" encoding="UTF-8"?> 
<records> 
    <customer num="1"> 
     <lastname>Smith</lastname> 
     <name>John</name> 
     <id>X45</id> 
    </customer> 
    <customer num="2"> 
     <lastname>George</lastname> 
     <name>Michael</name> 
     <id>X76</id> 
    </customer> 
    <customer num="3"> 
     <lastname>Ria</lastname> 
     <name>Chris</name> 
     <id>C87</id> 
    </customer> 
</records>