2017-06-14 44 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>