如何使用显式交叉引用对元素值进行分组?

时间:2013-07-11 12:58:36

标签: xml xslt

如何对元素的值进行分组< seg>在XML源代码中,使用@corresp属性创建的显式交叉引用?

<DIV>
<div id="fr">
  <seg id="fr_1" corresp="#en_1">abc</seg>
  <seg id="fr_2" corresp="#en_2 #en3">def</seg>
  <seg id="fr_3" corresp="#en_3 #en_4">ghi</seg>
  <seg id="fr_4" corresp="#en_4 #en_5">jkl</seg>
  <seg id="fr_5" corresp="#en_6">mno</seg>
</div>
<div id="en">
  <seg id="en_1" corresp="#fr_1">ab</seg>
  <seg id="en_2" corresp="#fr_1 #fr_2">cde</seg>
  <seg id="en_3" corresp="#fr_2 #fr_3">fg</seg>
  <seg id="en_4" corresp="#fr_3 #fr_4">hij</seg>
  <seg id="en_5" corresp="#fr_4">kl</seg>
  <seg id="en_6" corresp="#fr_5">mno</seg>
</div>
</DIV>

XSLT转换后的输出应如下所示:

<div>
  <ul>
    <li>abc<br/>ab</li>
    <li>abc<br/>cde</li>
    <li>def<br/>cde</li>
    <li>def<br/>fg</li>
    <li>ghi<br/>fg</li>
    <li>ghi<br/>hij</li>
    <li>jkl<br/>hij</li>
    <li>jkl<br/>kl</li>
    <li>mno<br/>mno</li>
 </ul>
</div>

谢谢!

@Jirka,这是一个类似的输入,但嵌套在元素中的其他元素。而corresp属性定义了这些新元素之间的交叉引用。修改后的输入如下所示:

<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>
 <ol>
  <li><w>AA</w> : <w>BX</w><br/><w>BB</w> : <w>AX</w><br/> </li>
  <li><w>DD</w> : <w>DX</w><w>EE</w> : <w>FX</w><br/><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 :(得分:0)

您可以尝试对answer稍微调整一下您的上一个问题:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:key name="kSegId" match="seg" use="@id"/>

    <xsl:template match="/DIV">
        <html>
            <head>
                <title></title>
            </head>
            <body>
                <ul>
                    <xsl:apply-templates select="div[@id='en']/seg"/>
                </ul>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="seg">
                <xsl:call-template name="findtarget">
                    <xsl:with-param name="targets" select="@corresp" />
                </xsl:call-template>

    </xsl:template>

    <xsl:template name="findtarget">
        <xsl:param name="targets" />
        <xsl:choose>
            <xsl:when test="contains($targets, ' ')">
                <xsl:call-template name="findtarget">
                    <xsl:with-param name="targets" select="substring-before($targets,' ')" />
                </xsl:call-template>
                <xsl:call-template name="findtarget">
                    <xsl:with-param name="targets" select="substring-after($targets,' ')" />
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <li>

                    <xsl:value-of select="key('kSegId',substring-after($targets, '#'))"/>
                    <br/>
                    <xsl:value-of select="."/>
                </li>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

将生成以下输出:

<?xml version="1.0"?>
<html>
  <head>
    <title/>
  </head>
  <body>
    <ul>
      <li>abc<br/>ab</li>
      <li>abc<br/>cde</li>
      <li>def<br/>cde</li>
      <li>def<br/>fg</li>
      <li>ghi<br/>fg</li>
      <li>ghi<br/>hij</li>
      <li>jkl<br/>hij</li>
      <li>jkl<br/>kl</li>
      <li>mno<br/>mno</li>
    </ul>
  </body>
</html>

答案 1 :(得分:0)

以下xslt可以正常工作

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/DIV">
        <div>
            <ul>
            <xsl:apply-templates select="div[@id = 'fr']/seg" />
            </ul>
        </div>
    </xsl:template>

    <xsl:template match="seg[../@id = 'fr']">
        <xsl:variable name="id" select="@id" />
        <xsl:variable name="text" select="." />

        <xsl:for-each select="//div[@id = 'en']/seg[contains(@corresp, $id)]">
            <li>
                <xsl:value-of select="$text" />
                <br />
                <xsl:value-of select="." />
            </li>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

这改变了我的输入

<?xml version="1.0" encoding="UTF-8"?>
<DIV>
    <div id="fr">
        <seg id="fr_1" corresp="#en_1">abc</seg>
        <seg id="fr_2" corresp="#en_2 #en3">def</seg>
        <seg id="fr_3" corresp="#en_3 #en_4">ghi</seg>
        <seg id="fr_4" corresp="#en_4 #en_5">jkl</seg>
        <seg id="fr_5" corresp="#en_6">mno</seg>
    </div>
    <div id="en">
        <seg id="en_1" corresp="#fr_1">ab</seg>
        <seg id="en_2" corresp="#fr_1 #fr_2">cde</seg>
        <seg id="en_3" corresp="#fr_2 #fr_3">fg</seg>
        <seg id="en_4" corresp="#fr_3 #fr_4">hij</seg>
        <seg id="en_5" corresp="#fr_4">kl</seg>
        <seg id="en_6" corresp="#fr_5">mno</seg>
    </div>
</DIV>

进入此输出

<?xml version="1.0" encoding="UTF-8"?>
<div xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <ul>
        <li>abc<br/>ab</li>
        <li>abc<br/>cde</li>
        <li>def<br/>cde</li>
        <li>def<br/>fg</li>
        <li>ghi<br/>fg</li>
        <li>ghi<br/>hij</li>
        <li>jkl<br/>hij</li>
        <li>jkl<br/>kl</li>
        <li>mno<br/>mno</li>
    </ul>
</div>

如果您需要html输出,则必须更改xsl:output声明,并在输入中添加一些html标记。