给定任意属性索引的XML元素值

时间:2011-12-02 08:41:28

标签: xml xslt indexing

背景

使用唯一标识符从XML元素列表中获取值。

问题

给定格式的XML文档:

<root xmlns:r="http://internet.com/network">
<r:equipment label="network">
  <r:item id="1">computer</r:item>
  <r:item id="2">network cable</r:item>
</r:equipment>
<r:equipment label="peripheral">
  <r:item id="3">printer</r:item>
  <r:item id="4">USB cable</r:item>
</r:equipment>

<r:install>
  <r:step action="identify"><r:item id="1" />, <r:item id="2" />, <r:item id="3" />, and <r:item id="4" /></r:step>
  <r:step action="unplug"><r:item id="2" /> from <r:item id="1" /></r:step>
  <r:step action="plug"><r:item id="4" /> into <r:item id="3" /></r:step>
  <r:step action="plug"><r:item id="4" /> into <r:item id="1" /></r:step>
</r:install>
</root>

目标是产生以下内容:

  1. 识别计算机,网络电缆,打印机和USB电缆
  2. 从计算机上拔下网络电缆
  3. 将USB线插入打印机
  4. 将USB线插入电脑
  5. 我尝试了以下内容:

    <xsl:template match="r:install">
    <p>
    Installation
    </p>
      <ol>
      <xsl:for-each select="r:step">
        <li><xsl:apply-templates select="." /></li>
      </xsl:for-each>
      </ol>
    </xsl:template>
    
    <xsl:template match="//root/r:install/r:step/r:item">
      ID: <xsl:value-of select="@id" />
    </xsl:template>
    

    换句话说,我想在<r:install>上匹配,然后使用任何id元素中的<r:item ... />属性。每个<r:step />都可以有多个<r:item id="X" />引用。这些引用对应于<r:item>...</r:item>元素列表中的<r:equipment ../>元素。

    每个id的{​​{1}}值都保证唯一。

    如果可能,我希望避免使用其他标记(例如<r:item />)。

    问题

    给定<r:item-ref id="X" />以及以下列表:

    <r:install><r:step action="unplug"><r:item id="4" /></r:step></r:install>

    相应的<r:equipment label="peripheral"> <r:item id="3">printer</r:item> <r:item id="4">USB cable</r:item> </r:equipment> XPath表达式在应用select上的模板时获取USB cable的值,该模板用作XML中任何位置的所述值的引用文件?

    谢谢!

1 个答案:

答案 0 :(得分:2)

这是使用密钥从 r:equipment 元素中查找 r:item 值的理想情况。

<xsl:key name="equipment" match="r:equipment/r:item" use="@id" />

因此,您“使用” @id 属性来查找 r:equipment / r:item 元素。要使用此密钥,假设您已定位在 r:step / r:item 元素之一上,则只需执行此操作...

<xsl:value-of select="key('equipment', @id)" />

这是完整的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:r="http://internet.com/network" exclude-result-prefixes="r">
   <xsl:output method="html" indent="yes"/>

   <xsl:key name="equipment" match="r:equipment/r:item" use="@id" />

   <xsl:template match="/root">
      <xsl:apply-templates select="r:install"/>
   </xsl:template>

   <xsl:template match="r:install">
      <p> Installation </p>
      <ol>
         <xsl:apply-templates select="r:step" />
      </ol>
   </xsl:template>

   <xsl:template match="r:step">
      <li>
         <xsl:value-of select="concat(@action, ' ')" />
         <xsl:apply-templates select="node()" />
      </li>
   </xsl:template>

   <xsl:template match="r:item"> 
      <xsl:value-of select="key('equipment', @id)" />
   </xsl:template>
</xsl:stylesheet>

应用于源XML时,会生成以下内容

<p> Installation </p>
<ol>
<li>identify computer, 
            network cable, 
            printer, and 
            USB cable</li>
<li>unplug network cable from 
            computer</li>
<li>plug USB cable into 
            printer</li>
<li>plug USB cable into 
            computer</li>
</ol>