我的输入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>
输出看起来像所需的输出加上以下内容:
<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递归模板。预先感谢。
此转换:
<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>