基于属性合并节点对,是模板匹配的新功能



假设我有以下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循环将是非常低效和坏主意,如何使用模板匹配,将这个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>
我对这类事情很模糊,所以非常感谢你的任何帮助!

下面的样式表:

<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>

使用键和纯"push-style "的解决方案:

<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>

最新更新