3

我是 xslt 的新手,请提供基于属性值比较两个节点的 xslt。

输入.xml:

<comp>
<alink>
<link id="0003"/>
<link id="0001"/>
<link id="0002"/>
 </alink>
<bibsection>
<bib id="0001">2007</bib>
 <bib id="0002">2008</bib>
<bib id="0003">2009</bib>
 </bibsection>
 </comp>

我的输出应该是,

输出.xml:

<comp>
<alink>
 <link id="0003"/><year>2009</year>
 <link id="0001"/><year>2007</year>
 <link id="0002"/><year>2008</year>
  </alink>
 <bibsection>
<bib id="0001">2007</bib>
 <bib id="0002">2008</bib>
 <bib id="0003">2009</bib>
  </bibsection>
  </comp>

提前致谢。

4

1 回答 1

1

一个完整、高效且简短的转换,使用键

<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="kBibById" match="bib" use="@id"/>

 <xsl:template match="node()|@*" name="identity">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="link">
  <xsl:call-template name="identity"/>
  <year><xsl:value-of select="key('kBibById', @id)"/></year>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时:

<comp>
    <alink>
        <link id="0003"/>
        <link id="0001"/>
        <link id="0002"/>
    </alink>
    <bibsection>
        <bib id="0001">2007</bib>
        <bib id="0002">2008</bib>
        <bib id="0003">2009</bib>
    </bibsection>
</comp>

产生了想要的正确结果:

<comp>
   <alink>
      <link id="0003"/>
      <year>2009</year>
      <link id="0001"/>
      <year>2007</year>
      <link id="0002"/>
      <year>2008</year>
   </alink>
   <bibsection>
      <bib id="0001">2007</bib>
      <bib id="0002">2008</bib>
      <bib id="0003">2009</bib>
   </bibsection>
</comp>

说明

  1. 身份规则“按原样”复制每个匹配的节点。

  2. 有一个覆盖标识模板的模板——它匹配任何link元素。该模板正文中的代码通过名称调用标识模板来处理匹配的link元素,然后构造一个year元素,其文本节点子节点的值是第一个元素的字符串值,该bib元素的属性与属性id值相同id匹配的link元素。使用引用名为“kBibById”的指令的函数来选择此bib元素。key()xsl:key

注意事项

上述身份规则的链接暂时无法使用——请暂时使用 Internet 档案中的这一表格:

http://web.archive.org/web/20081229160200/http://www.dpawson.co.uk/xsl/sect2/identity.html

于 2012-07-04T14:46:25.273 回答