首页 > 解决方案 > 在 XSL 中将文本转换为交叉引用

问题描述

我已经看到很多关于如何在 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 号引用正确的鞋店?</p>

标签: xmlxslt

解决方案


我将首先在变量中构建鞋店列表:

<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 则困难得多。


推荐阅读