对翻译单元进行分组并避免重复

时间:2015-01-12 16:49:09

标签: xml xslt xpath

我有一个包含多个翻译单元的XML文件。 "内容a"和"内容b"两者都有德语和法语的翻译。 "内容a"和"内容b"两者都在此文件中出现两次。

<unit>
     <src lang="en">Content a</src>
     <trg lang="de">Translation content a</trg>
</unit>

<unit>
     <src lang="en">Content a</src>
     <trg lang="fr">Translation content a</trg>
</unit>

<unit>
     <src lang="en">Content b</src>
     <trg lang="de">Translation content b</trg>
</unit>

<unit>
     <src lang="en">Content b</src>
     <trg lang="fr">Translation content b</trg>
 </unit>

我的目标是避免重复,所以这是我想要的输出:

    <unit>
         <src lang="en">Content a</src>
         <trg lang="de">Translation content a</trg>
         <trg lang="fr">Translation content a</trg>
    </unit>

    <unit>
         <src lang="en">Content b</src>
         <trg lang="de">Translation content b</trg>
         <trg lang="fr">Translation content b</trg>
    </unit>


     <unit>

到目前为止我的样式表:

<xsl:template match="unit">
        <xsl:copy>
            <xsl:copy-of select="src"/>
            <xsl:for-each-group select="current-group()/(* except src)" group-by="node-name(.)">
                <xsl:for-each-group select="current-group()" group-by=".">
                    <xsl:copy-of select="."/>
                </xsl:for-each-group>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>

它产生以下输出:

   <unit>
         <src lang="en">Content a</src>
         <trg lang="de">Translation content a</trg>
         <trg lang="fr">Translation content a</trg>
         <trg lang="de">Translation content b</trg>
         <trg lang="fr">Translation content b</trg>
    </unit>

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

给出格式良好的(!)输入,例如:

<units>
    <unit>
         <src lang="en">Content a</src>
         <trg lang="de">Translation content a</trg>
    </unit>

    <unit>
         <src lang="en">Content a</src>
         <trg lang="fr">Translation content a</trg>
    </unit>

    <unit>
         <src lang="en">Content b</src>
         <trg lang="de">Translation content b</trg>
    </unit>

    <unit>
         <src lang="en">Content b</src>
         <trg lang="fr">Translation content b</trg>
     </unit>
</units>

你可以使用:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/units">
    <xsl:copy>
        <xsl:for-each-group select="unit" group-by="src">
            <unit>
                <xsl:copy-of select="src"/>
                <xsl:copy-of select="current-group()/trg"/>
            </unit>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

生产:

<?xml version="1.0" encoding="UTF-8"?>
<units>
   <unit>
      <src lang="en">Content a</src>
      <trg lang="de">Translation content a</trg>
      <trg lang="fr">Translation content a</trg>
   </unit>
   <unit>
      <src lang="en">Content b</src>
      <trg lang="de">Translation content b</trg>
      <trg lang="fr">Translation content b</trg>
   </unit>
</units>

这假设所有src个元素都有lang ="en"。如果这不是一个有效的假设,请使用:

<xsl:for-each-group select="unit" group-by="concat(src/@lang, '|', src)">

代替。