2012-12-21 42 views
1

我輸入的XML看起來像這樣:數據的遞歸匹配,使一個層次樹

<AGROVOC xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 

<CONCEPT> 
    <Language>EN</Language> 
    <termcode>331000</termcode> 
    <termspell>site</termspell> 
    <NT>12861</NT> 
    <NT>13893</NT> 
    <NT>15988</NT> 
    <NT>24183</NT> 
    <NT>28623</NT> 
    <NT>35171</NT> 
    <NT>4781</NT> 
    <NT>5973</NT> 
    <NT>8872</NT> 
    <NT>9000162</NT> 
</CONCEPT> 

<CONCEPT> 
    <termcode>12861</termcode> 
    <termspell>child nurseries</termspell> 
    <BT>331000</BT> 
</CONCEPT> 

<CONCEPT> 
    <termcode>13893</termcode> 
    <termspell>restaurants</termspell> 
    <BT>331000</BT> 
</CONCEPT> 

<CONCEPT> 
    <termcode>15988</termcode> 
    <termspell>laboratories</termspell> 
    <BT>331000</BT> 
    <NT>24298</NT> 
</CONCEPT> 

<CONCEPT> 
    <termcode>24298</termcode> 
    <termspell>Veterinary laboratories</termspell> 
    <BT>15988</BT> 
</CONCEPT> 

<CONCEPT> 
    <termcode>24183</termcode> 
    <termspell>hospitals</termspell> 
    <BT>331000</BT> 
    <NT>16384</NT> 
</CONCEPT> 

<CONCEPT> 
    <termcode>16384</termcode> 
    <termspell>animal hospitals</termspell> 
    <BT>24183</BT> 
</CONCEPT> 

<CONCEPT> 
    <termcode>35171</termcode> 
    <termspell>Landfills</termspell> 
    <BT>331000</BT> 
    <NT>35165</NT> 
</CONCEPT> 

<CONCEPT> 
    <termcode>35165</termcode> 
    <termspell>waste landfills</termspell> 
    <BT>35171</BT> 
</CONCEPT> 

<CONCEPT> 
    <termcode>4781</termcode> 
    <termspell>meteorological stations</termspell> 
    <BT>331000</BT> 
    <NT>8342</NT> 
</CONCEPT> 

<CONCEPT> 
    <termcode>8342</termcode> 
    <termspell>Weather ships</termspell> 
    <BT>4781</BT> 
</CONCEPT> 

<CONCEPT> 
    <termcode>5973</termcode> 
    <termspell>plant nurseries</termspell> 
    <BT>331000</BT> 
    <NT>34832</NT> 
    <NT>34830</NT> 
    <NT>14969</NT> 
</CONCEPT> 

<CONCEPT> 
    <termcode>34832</termcode> 
    <termspell>Fruit tree nurseries</termspell> 
    <BT>5973</BT> 
</CONCEPT> 

<CONCEPT> 
    <termcode>34830</termcode> 
    <termspell>Forest nurseries</termspell> 
    <BT>5973</BT> 
</CONCEPT> 

<CONCEPT> 
    <termcode>14969</termcode> 
    <termspell>Ornamental tree nurseries</termspell> 
    <BT>5973</BT> 
</CONCEPT> 

<CONCEPT> 
    <termcode>8872</termcode> 
    <termspell>Apiaries</termspell> 
    <BT>331000</BT> 
</CONCEPT> 

<CONCEPT> 
    <termcode>9000162</termcode> 
    <termspell>Telecentre</termspell> 
    <BT>331000</BT> 
</CONCEPT> 

所需的輸出應該是這樣的:

<node id="331000" label="site"> 
    <isComposedBy> 
     <node id="12861" label="child nurseries"/> 
     <node id="13893" label="restaurants"/> 
     <node id="15988" label="laboratories"> 
      <isComposedBy> 
       <node id="24298" label="Veterinary laboratories"/> 
      </isComposedBy> 
     </node> 
     <node id="24183" label="hospitals"> 
      <isComposedBy> 
       <node id="16384" label="animal hospitals"/> 
      </isComposedBy> 
     </node> 
     <node id="35171" label="Landfills"> 
      <isComposedBy> 
       <node id="35165" label="waste landfills"/> 
      </isComposedBy> 
     </node> 
     <node id="4781" label="meteorological stations"> 
      <isComposedBy> 
       <node id="8342" label="Weather ships"/> 
      </isComposedBy> 
     </node> 
     <node id="5973" label="plant nurseries"> 
      <isComposedBy> 
       <node id="34832" label="Fruit tree nurseries"/> 
       <node id="34830" label="Forest nurseries"/> 
       <node id="14969" label="Ornamental tree nurseries"/> 
      </isComposedBy> 
     </node> 
     <node id="8872" label="Apiaries"/> 
     <node id="9000162" label="Telecentre"/> 
    </isComposedBy> 
</node> 

從在上面給定的xml中,一個概念只能有1個BT或更廣泛的術語,它是其父代的ID。如果它不包含BT,則表示它位於層次結構的頂部(例如網站)。一個概念可以有多個NT或兒童。

我的XSL是這樣的:

<xsl:key name="kChildren" match="CONCEPT" use="BT"/> 
    <xsl:template match="CONCEPT"> 
    <xsl:element name="node"> 
     <xsl:attribute name="id"> 
      <xsl:value-of select="/AGROVOC/CONCEPT/termcode"/> 
     </xsl:attribute> 
     <xsl:apply-templates select="key('kChildren', '0')"/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="CONCEPT"> 
    <xsl:element name="node"> 
     <xsl:attribute name="id"> 
      <xsl:value-of select="termcode"/> 
     </xsl:attribute> 
     <xsl:attribute name="label"> 
      <xsl:value-of select="termspell"/> 
     </xsl:attribute> 
     <xsl:if test="key('kChildren', termcode)"> 
      <isComposedBy> 
       <xsl:apply-templates select="key('kChildren', termcode)"/> 
      </isComposedBy> 
     </xsl:if> 
    </xsl:element> 
</xsl:template> 

輸出類似於所需的輸出PLUS這樣:

<node id="12861" label="child nurseries"/> 
<node id="13893" label="restaurants"/> 
<node id="15988" label="laboratories"> 
    <isComposedBy> 
     <node id="24298" label="Veterinary laboratories"/> 
    </isComposedBy> 
</node> 
<node id="24298" label="Veterinary laboratories"/> 
<node id="24183" label="hospitals"> 
    <isComposedBy> 
     <node id="16384" label="animal hospitals"/> 
    </isComposedBy> 
</node> 
<node id="16384" label="animal hospitals"/> 
<node id="35171" label="Landfills"> 
    <isComposedBy> 
     <node id="35165" label="waste landfills"/> 
    </isComposedBy> 
</node> 
<node id="35165" label="waste landfills"/> 
<node id="4781" label="meteorological stations"> 
    <isComposedBy> 
     <node id="8342" label="Weather ships"/> 
    </isComposedBy> 
</node> 
<node id="8342" label="Weather ships"/> 
<node id="5973" label="plant nurseries"> 
    <isComposedBy> 
     <node id="34832" label="Fruit tree nurseries"/> 
     <node id="34830" label="Forest nurseries"/> 
     <node id="14969" label="Ornamental tree nurseries"/> 
    </isComposedBy> 
</node> 
<node id="34832" label="Fruit tree nurseries"/> 
<node id="34830" label="Forest nurseries"/> 
<node id="14969" label="Ornamental tree nurseries"/> 
<node id="8872" label="Apiaries"/> 
<node id="9000162" label="Telecentre"/> 

任何想法如何,我可以刪除只是額外的節點重複?順便說一句,我從這個職位圖案我的xsl:xslt recursive template on parent-child data。提前致謝。

+0

euler,在提供的輸出「plant nurseries」中有三個孩子,但在提供的源XML文檔中,「plant nurseries」沒有任何孩子。請修改並更正。 –

+0

@DimitreNovatchev,非常感謝,這很快!豎起大拇指給你!;-) – euler

+0

euler,不客氣。 –

回答

1

該轉化

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:key name="kConcByCode" match="CONCEPT" use="termcode"/> 

<xsl:template match="/"> 
    <xsl:apply-templates select="/*/CONCEPT[not(BT)]"/> 
</xsl:template> 

<xsl:template match="CONCEPT"> 
    <node id="{termcode}" label="{termspell}"> 
    <xsl:if test="key('kConcByCode', NT)"> 
    <isComposedBy> 
     <xsl:apply-templates select="key('kConcByCode', NT)"/> 
    </isComposedBy> 
    </xsl:if> 
    </node> 
</xsl:template> 
</xsl:stylesheet> 

當所提供的XML文檔施加:

<AGROVOC xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <CONCEPT> 
     <Language>EN</Language> 
     <termcode>331000</termcode> 
     <termspell>site</termspell> 
     <NT>12861</NT> 
     <NT>13893</NT> 
     <NT>15988</NT> 
     <NT>24183</NT> 
     <NT>28623</NT> 
     <NT>35171</NT> 
     <NT>4781</NT> 
     <NT>5973</NT> 
     <NT>8872</NT> 
     <NT>9000162</NT> 
    </CONCEPT> 
    <CONCEPT> 
     <termcode>12861</termcode> 
     <termspell>child nurseries</termspell> 
     <BT>331000</BT> 
    </CONCEPT> 
    <CONCEPT> 
     <termcode>13893</termcode> 
     <termspell>restaurants</termspell> 
     <BT>331000</BT> 
    </CONCEPT> 
    <CONCEPT> 
     <termcode>15988</termcode> 
     <termspell>laboratories</termspell> 
     <BT>331000</BT> 
     <NT>24298</NT> 
    </CONCEPT> 
    <CONCEPT> 
     <termcode>24298</termcode> 
     <termspell>Veterinary laboratories</termspell> 
     <BT>15988</BT> 
    </CONCEPT> 
    <CONCEPT> 
     <termcode>24183</termcode> 
     <termspell>hospitals</termspell> 
     <BT>331000</BT> 
     <NT>16384</NT> 
    </CONCEPT> 
    <CONCEPT> 
     <termcode>16384</termcode> 
     <termspell>animal hospitals</termspell> 
     <BT>24183</BT> 
    </CONCEPT> 
    <CONCEPT> 
     <termcode>35171</termcode> 
     <termspell>Landfills</termspell> 
     <BT>331000</BT> 
     <NT>35165</NT> 
    </CONCEPT> 
    <CONCEPT> 
     <termcode>35165</termcode> 
     <termspell>waste landfills</termspell> 
     <BT>35171</BT> 
    </CONCEPT> 
    <CONCEPT> 
     <termcode>4781</termcode> 
     <termspell>meteorological stations</termspell> 
     <BT>331000</BT> 
     <NT>8342</NT> 
    </CONCEPT> 
    <CONCEPT> 
     <termcode>8342</termcode> 
     <termspell>Weather ships</termspell> 
     <BT>4781</BT> 
    </CONCEPT> 
    <CONCEPT> 
     <termcode>5973</termcode> 
     <termspell>plant nurseries</termspell> 
     <BT>331000</BT> 
    </CONCEPT> 
    <CONCEPT> 
     <termcode>34832</termcode> 
     <termspell>Fruit tree nurseries</termspell> 
     <BT>5973</BT> 
    </CONCEPT> 
    <CONCEPT> 
     <termcode>34830</termcode> 
     <termspell>Forest nurseries</termspell> 
     <BT>5973</BT> 
    </CONCEPT> 
    <CONCEPT> 
     <termcode>14969</termcode> 
     <termspell>Ornamental tree nurseries</termspell> 
     <BT>5973</BT> 
    </CONCEPT> 
    <CONCEPT> 
     <termcode>8872</termcode> 
     <termspell>Apiaries</termspell> 
     <BT>331000</BT> 
    </CONCEPT> 
    <CONCEPT> 
     <termcode>9000162</termcode> 
     <termspell>Telecentre</termspell> 
     <BT>331000</BT> 
    </CONCEPT> 
</AGROVOC> 

產生正確的結果

<node id="331000" label="site"> 
    <isComposedBy> 
     <node id="12861" label="child nurseries"/> 
     <node id="13893" label="restaurants"/> 
     <node id="15988" label="laboratories"> 
     <isComposedBy> 
      <node id="24298" label="Veterinary laboratories"/> 
     </isComposedBy> 
     </node> 
     <node id="24183" label="hospitals"> 
     <isComposedBy> 
      <node id="16384" label="animal hospitals"/> 
     </isComposedBy> 
     </node> 
     <node id="35171" label="Landfills"> 
     <isComposedBy> 
      <node id="35165" label="waste landfills"/> 
     </isComposedBy> 
     </node> 
     <node id="4781" label="meteorological stations"> 
     <isComposedBy> 
      <node id="8342" label="Weather ships"/> 
     </isComposedBy> 
     </node> 
     <node id="5973" label="plant nurseries"/> 
     <node id="8872" label="Apiaries"/> 
     <node id="9000162" label="Telecentre"/> 
    </isComposedBy> 
</node>