我已经看到了很多有关如何在XSL中分解XML交叉引用的信息(例如XSL cross-reference)。我完全坚持如何做相反的事情。我什至不知道它在技术上叫什么,所以我也不知道在哪里查找。
给出XML
<shoes>
<shoe>
<colour>brown</colour>
<make>Shoeco</make>
</shoe>
<shoe>
<colour>black</colour>
<make>Shoeco</make>
</shoe>
<shoe>
<colour>purple</colour>
<make>Footfine</make>
</shoe>
<shoe>
<colour>brown</colour>
<make>Footfine</make>
</shoe>
<shoe>
<colour>blue</colour>
<make>Leathers</make>
</shoe>
</shoes>
我想要输出
<inventory>
<shoelist>
<item>
<colour>brown</colour>
<shopref>1</shopref>
</item>
<item>
<colour>black</colour>
<shopref>1</shopref>
</item>
<item>
<colour>purple</colour>
<shopref>1</shopref>
</item>
<item>
<colour>brown</colour>
<shopref>2</shopref>
</item>
<item>
<colour>blue</colour>
<shopref>2</shopref>
</item>
</shoelist>
<shoeshops>
<shop>
<refno>1</refno>
<name>ShoeCo</name>
</shop>
<shop>
<refno>2</refno>
<name>FootFine</name>
</shop>
<shop>
<refno>3</refno>
<name>Leathers</name>
</shop>
</shoeshops>
</inventory>
我如何(a)为每个唯一的鞋店创建一个ID递增的列表,并(b)在每个鞋元素中按ID号引用正确的鞋店?
答案 0 :(得分:2)
我首先将变量建立鞋店列表:
<xsl:variable name="shops">
<shoeshops>
<xsl:for-each-group select="shoe" group-by="make">
<shop>
<refno>{position()}</refno>
<name>{current-grouping-key()}</name>
</shop>
</xsl:for-each-group>
</shoeshops>
</xsl:variable>
然后创建鞋单:
<xsl:mode on-no-match="shallow-copy"/>
<inventory>
<shoelist>
<xsl:apply-templates select="shoes/shoe"/>
</shoelist>
<xsl:copy-of select="$shops"/>
</inventory>
<xsl:template match="make">
<shopref>{$shops//shop[name="current()"]/refno}</shopref>
</xsl:template>
为了简洁起见,它使用了一些XSLT 3.0构造。转换为XSLT 2.0非常容易,而转换为XSLT 1.0则困难得多。