2012-01-20 137 views
1

我想弄清楚如何使用xslt將平面xml文件轉換爲嵌套xml文件。 下面是我試圖轉換的flat xml的一個例子。我使用xslt 2,所以我可以使用分組命令,但我不知道如何。將平面XML轉換爲嵌套XML

產生的結構我正在尋找的是:

<sources> 
<sourcetype> 
    <sourcetypename>Career Fair</sourcetypename> 
    <sourcelist> 
    <source> 
    <sourcename>Ann Arbor News Fair</sourcename> 
    <sourceid>CFE-10001</sourceid> 
    <eventlist> 
     <event> 
     <eventname></eventname> 
     <eventid></eventid> 
     </event> 
    </eventlist> 
    </source> 
    </sourcelist> 
</sourcetype> 
</sources> 

---平整的XML ----

<?xml version="1.0" encoding="UTF-8"?> 
<ExportXML xmlns:ns1="http://www.taleo.com/ws/integration/toolkit/2005/07" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.taleo.com/ws/integration/toolkit/2005/07" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <record> 
     <field name="TypeName">Billboards</field> 
     <field name="SourceName">Billboard</field> 
     <field name="SourceID">BLD-200284</field> 
     <field name="EventName"></field> 
     <field name="EventID"></field> 
     <field name="State">Active</field> 
    </record> 
    <record> 
     <field name="TypeName">Career Fair</field> 
     <field name="SourceName">Ann Arbor News Fair</field> 
     <field name="SourceID">CFE-10001</field> 
     <field name="EventName"></field> 
     <field name="EventID"></field> 
     <field name="State">Active</field> 
    </record> 
    <record> 
     <field name="TypeName">Career Fair</field> 
     <field name="SourceName">Black Data Processing Association (BDPA) </field> 
     <field name="SourceID">CFE-10002</field> 
     <field name="EventName"></field> 
     <field name="EventID"></field> 
     <field name="State">Active</field> 
    </record> 
    <record> 
     <field name="TypeName">Career Fair</field> 
     <field name="SourceName">Career Concepts</field> 
     <field name="SourceID">CFE-10760</field> 
     <field name="EventName"></field> 
     <field name="EventID"></field> 
     <field name="State">Active</field> 
    </record> 
    </ExportXML> 
+0

你想如何分組?是否每個''都是新的''? –

回答

1

嵌套一堆for-each-group要素開始顯得非常討厭,但它能夠完成任務:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:t="http://www.taleo.com/ws/integration/toolkit/2005/07"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:template match="/"> 
     <sources> 
      <xsl:for-each-group select="/*/t:record" 
       group-by="t:field[@name='TypeName']"> 
       <sourcetype> 
        <sourcetypename> 
         <xsl:value-of select="current-grouping-key()"/> 
        </sourcetypename> 
        <sourcelist> 
         <xsl:for-each-group select="current-group()" 
          group-by="t:field[@name='SourceID']"> 
          <source> 
           <sourcename> 
            <xsl:value-of select="t:field[@name='SourceName']"/> 
           </sourcename> 
           <sourceid> 
            <xsl:value-of select="current-grouping-key()"/> 
           </sourceid> 
           <eventlist> 
            <xsl:for-each-group 
             select="current-group()" group-by="t:field[@name='EventID']"> 
             <event> 
              <eventname> 
               <xsl:value-of 
                select="t:field[@name='EventName']"/> 
              </eventname> 
              <eventid> 
               <xsl:value-of 
                select="current-grouping-key()"/> 
              </eventid> 
             </event> 
            </xsl:for-each-group> 
           </eventlist> 
          </source> 
         </xsl:for-each-group> 
        </sourcelist> 
       </sourcetype> 
      </xsl:for-each-group> 
     </sources> 
    </xsl:template> 
</xsl:stylesheet> 

輸出:

<sources xmlns:t="http://www.taleo.com/ws/integration/toolkit/2005/07"> 
    <sourcetype> 
     <sourcetypename>Billboards</sourcetypename> 
     <sourcelist> 
     <source> 
      <sourcename>Billboard</sourcename> 
      <sourceid>BLD-200284</sourceid> 
      <eventlist> 
       <event> 
        <eventname/> 
        <eventid/> 
       </event> 
      </eventlist> 
     </source> 
     </sourcelist> 
    </sourcetype> 
    <sourcetype> 
     <sourcetypename>Career Fair</sourcetypename> 
     <sourcelist> 
     <source> 
      <sourcename>Ann Arbor News Fair</sourcename> 
      <sourceid>CFE-10001</sourceid> 
      <eventlist> 
       <event> 
        <eventname/> 
        <eventid/> 
       </event> 
      </eventlist> 
     </source> 
     <source> 
      <sourcename>Black Data Processing Association (BDPA) </sourcename> 
      <sourceid>CFE-10002</sourceid> 
      <eventlist> 
       <event> 
        <eventname/> 
        <eventid/> 
       </event> 
      </eventlist> 
     </source> 
     <source> 
      <sourcename>Career Concepts</sourcename> 
      <sourceid>CFE-10760</sourceid> 
      <eventlist> 
       <event> 
        <eventname/> 
        <eventid/> 
       </event> 
      </eventlist> 
     </source> 
     </sourcelist> 
    </sourcetype> 
</sources> 
0

我在最終輸出猜測了,因爲我不太確定分組應該是什麼樣的,但這裏的另一個2.0分組解決方案:

XSLT 2.0

<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="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="/*:ExportXML"> 
    <sources> 
     <xsl:for-each-group select="*:record" group-by="*:field[@name='TypeName']"> 
     <xsl:variable name="vType" select="*:field[@name='TypeName']"/> 
     <sourcetype> 
      <sourcetypename> 
      <xsl:apply-templates select="*:field[@name='TypeName']" mode="title"/> 
      </sourcetypename> 
      <sourcelist> 
      <xsl:apply-templates select="/*/*:record[*:field[@name='TypeName'][.=$vType]]"/> 
      </sourcelist> 
     </sourcetype> 
     </xsl:for-each-group> 
    </sources> 
    </xsl:template> 

    <xsl:template match="*:field"> 
    <xsl:element name="{lower-case(@name)}"> 
     <xsl:apply-templates/>  
    </xsl:element> 
    </xsl:template> 

    <xsl:template match="*:record"> 
    <source> 
     <xsl:apply-templates select="*:field[starts-with(@name,'Source')]"/> 
     <eventlist> 
     <event> 
      <xsl:apply-templates select="*:field[starts-with(@name,'Event')]"/> 
     </event> 
     </eventlist> 
    </source> 
    </xsl:template> 

    <xsl:template match="*:field[@name='TypeName']"/> 

    <xsl:template match="*:field[@name='TypeName']" mode="title"> 
    <xsl:apply-templates/> 
    </xsl:template> 

</xsl:stylesheet> 

XML輸出(使用提供的XML輸入和Saxon-HE 9.3)

<sources> 
    <sourcetype> 
     <sourcetypename>Billboards</sourcetypename> 
     <sourcelist> 
     <source> 
      <sourcename>Billboard</sourcename> 
      <sourceid>BLD-200284</sourceid> 
      <eventlist> 
       <event> 
        <eventname/> 
        <eventid/> 
       </event> 
      </eventlist> 
     </source> 
     </sourcelist> 
    </sourcetype> 
    <sourcetype> 
     <sourcetypename>Career Fair</sourcetypename> 
     <sourcelist> 
     <source> 
      <sourcename>Ann Arbor News Fair</sourcename> 
      <sourceid>CFE-10001</sourceid> 
      <eventlist> 
       <event> 
        <eventname/> 
        <eventid/> 
       </event> 
      </eventlist> 
     </source> 
     <source> 
      <sourcename>Black Data Processing Association (BDPA) </sourcename> 
      <sourceid>CFE-10002</sourceid> 
      <eventlist> 
       <event> 
        <eventname/> 
        <eventid/> 
       </event> 
      </eventlist> 
     </source> 
     <source> 
      <sourcename>Career Concepts</sourcename> 
      <sourceid>CFE-10760</sourceid> 
      <eventlist> 
       <event> 
        <eventname/> 
        <eventid/> 
       </event> 
      </eventlist> 
     </source> 
     </sourcelist> 
    </sourcetype> 
</sources>