2013-07-17 43 views
0

我在這個問題上停留了一段時間。我有這樣一個示例XML文件:使用XSLT轉換XML文件(組合多個模板)

<Records> 
<Record><Id>1</Id><Name>table_id</Name><Attribute></Attribute><Value>1</Value></Record> 
<Record><Id>1</Id><Name>score</Name><Attribute></Attribute><Value>2.1</Value></Record> 
<Record><Id>1</Id><Name>custom4</Name><Attribute>name</Attribute><Value>Custom411</Value></Record> 
<Record><Id>1</Id><Name>custom4</Name><Attribute>name</Attribute><Value>Custom412</Value></Record> 
<Record><Id>2</Id><Name>table_id</Name><Attribute></Attribute><Value>2</Value></Record> 
<Record><Id>2</Id><Name>title</Name><Attribute></Attribute><Value>Title 2</Value></Record> 
</Records> 

我想所有的ID和行合併到這種格式使用XSLT另一個單獨的XML文件:

<RECORDS> 
<RECORD> 
    <ITEM name="table_id" value="1"/> 
    <ITEM name="score" value="2.1"/> 
    <LIST name="custom4"> 
    <LIST_ITEM value="custom411"/> 
    <LIST_ITEM value="custom412"/> 
    </LIST> 
</RECORD> 
<RECORD> 
    <ITEM name="table_id" value="2"/> 
    <ITEM name="title" value="Title 2"/> 
</RECORD> 
</RECORDS 

<table_id> = <Id>本質價值。因此,對於每個<Id>,我需要創建一個<RECORD>。如果一個<Id>存在多個相同的<Name>值,那麼我需要爲該<name>創建一個LIST_ITEM,否則創建一個正常的ITEM。

到目前爲止,我已經能夠使用模板根據<Id>對記錄進行分組。但我無法使用此模板的輸出生成最終輸出:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template match="/"> 
    <xsl:variable name="output"> 
     <xsl:call-template name="groupById" /> 
    </xsl:variable> 

    <OBJECTS> 
    <xsl:for-each select="$output/Root/Records"> 
     <OBJECT> 
      <xsl:for-each select="Id/Record"> 
       <ITEM> 
        <xsl:attribute name='name'> 
         <xsl:value-of select="Name" /> 
        </xsl:attribute> 
        <xsl:attribute name='value'> 
         <xsl:value-of select="Value" /> 
        </xsl:attribute> 
       </ITEM> 
      </xsl:for-each> 
     </OBJECT> 
    </xsl:for-each> 
    </OBJECTS> 
</xsl:template> 

<xsl:template name="groupById"> 
    <Root> 
     <xsl:for-each-group select="/Records/Record" group-by="Id"> 
     <Records> 
     <xsl:for-each-group select="current-group()" group-by="if(Id) then Id else 'no key'"> 
      <!-- Copy attributes off the *first* Record element in the group --> 
      <xsl:copy-of select="current-group()[1]/Id"/> 
      <!-- Copy remaining children from *all* Record elements in the group --> 
      <xsl:copy-of select="current-group()"/> 
     </xsl:for-each-group> 
     </Records> 
     </xsl:for-each-group> 
    </Root> 
</xsl:template> 

</xsl:stylesheet> 

任何人都可以從這裏引導我,或者建議替代路線嗎?

回答

1

下面是一個簡短但完整的XSLT 2.0樣式表:

<xsl:stylesheet 
    version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xs"> 

<xsl:output method="xml" indent="yes"/> 

<xsl:template match="Records"> 
    <RECORDS> 
    <xsl:for-each-group select="Record" group-by="Id"> 
     <RECORD> 
     <ITEM name="table_id" value="{current-grouping-key()}"/> 
     <xsl:for-each-group select="current-group()[not(Name = 'table_id')]" group-by="Name"> 
      <xsl:choose> 
      <xsl:when test="current-group()[2]"> 
       <LIST name="{current-grouping-key()}"> 
       <xsl:for-each select="current-group()"> 
        <LIST_ITEM value="{Value}"/> 
       </xsl:for-each> 
       </LIST> 
      </xsl:when> 
      <xsl:otherwise> 
       <ITEM name="{Name}" value="{Value}"/> 
      </xsl:otherwise> 
      </xsl:choose> 
     </xsl:for-each-group> 
    </RECORD> 
    </xsl:for-each-group> 
</RECORDS> 
</xsl:template> 

</xsl:stylesheet> 

使用撒克遜9,它把輸入

<Records> 
    <Record> 
    <Id>1</Id> 
    <Name>table_id</Name> 
    <Attribute></Attribute> 
    <Value>1</Value> 
    </Record> 
    <Record> 
    <Id>1</Id> 
    <Name>score</Name> 
    <Attribute></Attribute> 
    <Value>2.1</Value> 
    </Record> 
    <Record> 
    <Id>1</Id> 
    <Name>custom4</Name> 
    <Attribute>name</Attribute> 
    <Value>Custom411</Value> 
    </Record> 
    <Record> 
    <Id>1</Id> 
    <Name>custom4</Name> 
    <Attribute>name</Attribute> 
    <Value>Custom412</Value> 
    </Record> 
    <Record> 
    <Id>2</Id> 
    <Name>table_id</Name> 
    <Attribute></Attribute> 
    <Value>2</Value> 
    </Record> 
    <Record> 
    <Id>2</Id> 
    <Name>title</Name> 
    <Attribute></Attribute> 
    <Value>Title 2</Value> 
    </Record> 
</Records> 

到以下結果:

<RECORDS> 
    <RECORD> 
     <ITEM name="table_id" value="1"/> 
     <ITEM name="score" value="2.1"/> 
     <LIST name="custom4"> 
     <LIST_ITEM value="Custom411"/> 
     <LIST_ITEM value="Custom412"/> 
     </LIST> 
    </RECORD> 
    <RECORD> 
     <ITEM name="table_id" value="2"/> 
     <ITEM name="title" value="Title 2"/> 
    </RECORD> 
</RECORDS> 
+0

非常感謝你很多,解決方案是優雅的。我完全在另一個軌道上! – Rg90