基于属性合并节点对,新模板匹配

时间:2011-05-04 17:30:24

标签: xslt xpath template-matching

说我有以下XML:

<root>
   <tokens>
      <token ID="t1">blah</token>
      <token ID="t2">blabla</token>
      <token ID="t3">shovel</token>
   </tokens>

   <relatedStuff>
      <group gID="s1">
        <references tokID="t1"/>
        <references tokID="t2"/>
      </group>

      <group gID="s2">
        <references tokID="t3"/>
      </group>

   </relatedStuff>
</root>

现在,考虑到每个令牌的for-each循环效率非常低且a bad idea,如何使用模板匹配将这个xml转换为以下内容?

<s id="everything_merged"> 
    <tok id="t1" gID="s1" >blah</tok> 
    <tok id="t2" gID="s1" >blabla</tok> 

    <tok id="t3" gID="s2" >shovel</tok>
</s> 

<s>所需的全部内容是“gID”,即与<tokens>中的令牌对应的gID。

<xsl:for-each select="b:root/a:tokens/a:token">
    <!-- and here some template matching -->
    <xsl:attribute name="gID">
         <xsl:value-of select="--correspondingNode's--@gID"/>
    </xsl:attribute>

</xsl:for-each>

我对这类事情很模糊,所以非常感谢你的帮助!

2 个答案:

答案 0 :(得分:2)

以下样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <s id="everything_merged">
            <xsl:apply-templates select="/root/tokens/token" />
        </s>
    </xsl:template>
    <xsl:template match="token">
        <tok id="{@ID}" gID="{/root/relatedStuff/group[
                                references[@tokID=current()/@ID]]/@gID}">
            <xsl:apply-templates />
        </tok>
    </xsl:template>
</xsl:stylesheet>

应用于此输入(针对良好形状进行校正):

<root>
    <tokens>
        <token ID="t1">blah</token>
        <token ID="t2">blabla</token>
        <token ID="t3">shovel</token>
    </tokens>
    <relatedStuff>
        <group gID="s1">
            <references tokID="t1" />
            <references tokID="t2" />
        </group>
        <group gID="s2">
            <references tokID="t3" />
        </group>
    </relatedStuff>
</root>

产地:

<s id="everything_merged">
    <tok id="t1" gID="s1">blah</tok>
    <tok id="t2" gID="s1">blabla</tok>
    <tok id="t3" gID="s2">shovel</tok>
</s>

答案 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="kgIDfromTokId" match="@gID"
  use="../*/@tokID"/>

 <xsl:template match="tokens">
  <s id="everything_merged">
   <xsl:apply-templates/>
  </s>
 </xsl:template>

 <xsl:template match="token">
  <tok id="{@ID}" gID="{key('kgIDfromTokId', @ID)}">
   <xsl:apply-templates/>
  </tok>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档

<root>
    <tokens>
        <token ID="t1">blah</token>
        <token ID="t2">blabla</token>
        <token ID="t3">shovel</token>
    </tokens>
    <relatedStuff>
        <group gID="s1">
            <references tokID="t1" />
            <references tokID="t2" />
        </group>
        <group gID="s2">
            <references tokID="t3" />
        </group>
    </relatedStuff>
</root>

产生了想要的正确结果

<s id="everything_merged">
   <tok id="t1" gID="s1">blah</tok>
   <tok id="t2" gID="s1">blabla</tok>
   <tok id="t3" gID="s2">shovel</tok>
</s>