在XSL

时间:2018-09-25 16:45:14

标签: xml xslt

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

1 个答案:

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