如何使用由其属性定义的交叉引用对元素的值进行分组?

时间:2013-07-12 19:45:42

标签: xml xslt

如何对多个< div>中的元素进行分组阻止它们是否具有唯一的ID以及由对应的atrributes创建的交叉引用。元素可以具有相应的匹配或者可以不具有。如果它们不匹配,则corresp atrribute包含零值。当将翻译的单词与原始文本中的对应单词链接时,可能发生这种匹配的真实上下文。 XML输入示例如下所示:

<DIV>
 <div id="fr">
  <seg id="fr_1"><w id="fr1" corresp="#en2">AA</w> <w id="fr2" corresp="#en3">BB</w>, <w id="fr3" corresp="#en1">CC</w>.</seg>
  <seg id="fr_2"><w id="fr1" corresp="#en1">DD</w> <w id="fr2" corresp="#en3">EE</w>?</seg>
  <seg id="fr_3"><w id="fr1" corresp="#en1">FF</w> <w id="fr2" corresp="#en3">GG</w><w id="fr3" corresp="#en2">HH</w></seg>
 </div>
 <div id="en">
  <seg id="en_1"><w id="en1" corresp="#fr3">AX</w><w id="en2" corresp="#fr1">BX</w><w id="en3" corresp="#fr2">CX</w></seg>
  <seg id="en_2"><w id="en1" corresp="#fr1">DX</w><w id="en2" corresp="#en0">EX</w><w id="en3" corresp="#en2">FX</w></seg> 
  <seg id="en_3"><w id="en1" corresp="#fr1">HX</w> <w id="en2" corresp="#en3">IX</w><w id="en3" corresp="#en2">JX</w>.</seg>
 </div>
</DIV>

如果要通过corresp属性跟随链接路径,输出应如下所示:

<div>
 <ol>
   <li><w>AA</w> : <w>BX</w><br/> <w>BB</w> : <w>CX</w><br/> <w>CC</w> : <w>AX</w> <br/> </li>
   <li><w>DD</w> : <w>DX</w><br/> <w>EE</w> : <w>FX</w><br/> </li>
   <li><w>FF</w> : <w>HX</w><br/> <w>GG</w> : <w>JX</w><br/> <w>HH</w> : <w>IX</w><br/></li>
 </ol>
</div>

谢谢!

2 个答案:

答案 0 :(得分:1)

要查找其他元素,通常最好使用密钥。在查找相应的元素时,您似乎希望将 seg 的ID考虑在内,在这种情况下,您可以像这样定义您的密钥:

<xsl:key name="corresp" match="w" use="concat(substring-after(../@id, '_'), '#', @id)" />

然后,假设您被定位在 w 元素上,要查找相应的值,您可以使用这样的键:

<xsl:value-of select="key('corresp', concat(substring-after(../@id, '_'), @corresp))" />

这是完整的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:key name="corresp" match="w" use="concat(substring-after(../@id, '_'), '#', @id)"/>

   <xsl:template match="div[@id='fr']">
      <ol>
         <xsl:apply-templates/>
      </ol>
   </xsl:template>

   <xsl:template match="div[@id='en']"/>

   <xsl:template match="seg">
      <li>
         <xsl:apply-templates select="w"/>
      </li>
   </xsl:template>

   <xsl:template match="w">
      <w>
         <xsl:value-of select="."/>
      </w>
      <xsl:text> : </xsl:text>
      <w>
         <xsl:value-of select="key('corresp', concat(substring-after(../@id, '_'), @corresp))"/>
      </w>
      <br/>
   </xsl:template>

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

应用于XML时,输出以下内容

<DIV>
   <ol>
      <li>
         <w>AA</w> : <w>BX</w><br/><w>BB</w> : <w>CX</w><br/><w>CC</w> : <w>AX</w><br/>
      </li>
      <li>
         <w>DD</w> : <w>DX</w><br/><w>EE</w> : <w>FX</w><br/>
      </li>
      <li>
         <w>FF</w> : <w>HX</w><br/><w>GG</w> : <w>JX</w><br/><w>HH</w> : <w>IX</w><br/>
      </li>
   </ol>
</DIV>

你在问题​​中提到“如果它们不匹配,则对应的atrribute包含零值”,但是没有举例说明。你可以做的是将上面的结果存储在一个变量中,然后只需要一个 xsl:choose 来输出一个零。这样的事,也许......

 <xsl:variable name="value" 
               select="key('corresp', concat(substring-after(../@id, '_'), @corresp))"/>
 <xsl:choose>
     <xsl:when test="string-length($value) > 0"><xsl:value-of select="$value" /><xsl:when>
     <xsl:otherwise>0</xsl:otherwise>
 </xsl:choose>

答案 1 :(得分:0)

稍微直截了当你可以试试这个:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="kId" match="seg/w" use="@id"/>
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/DIV">
        <div>
            <ol>
                <xsl:apply-templates select="div[@id='fr']/seg"/>
            </ol>
        </div>
    </xsl:template>
    <xsl:template match="div/seg">
            <li>
                <xsl:for-each select="w" >
                    <w><xsl:value-of select="."/></w>
                    <xsl:text> : </xsl:text>
                    <w>
                        <xsl:value-of select="key('kId',substring-after(@corresp, '#'))"/>
                    </w>
                    <br/>
                </xsl:for-each>
            </li>
    </xsl:template>
</xsl:stylesheet>

将产生以下输出:

<?xml version="1.0"?>
<div>
  <ol>
    <li><w>AA</w> : <w>BX</w><br/><w>BB</w> : <w>CX</w><br/><w>CC</w> : <w>AX</w><br/></li>
    <li><w>DD</w> : <w>AX</w><br/><w>EE</w> : <w>CX</w><br/></li>
    <li><w>FF</w> : <w>AX</w><br/><w>GG</w> : <w>CX</w><br/><w>HH</w> : <w>BX</w><br/></li>
  </ol>
</div>