1

以下を機能させるのに少し苦労しています:翻訳されたノードをマージしようとしていますが、ノードセット間にわずかな違いがある場合があるため、目隠しをしてこれを行うことはできず、手動で確認する必要があります。しかし同時に、私は自分の人生をシンプルに保つのが好きなので、可能な限り前もって自動化したいと思っています。以下の例を見てください:

<root>
<chapter>
<string class="l1"><local xml:lang="en">Some English here</local></string>
<string class="p"><local xml:lang="en">Some other English here</local></string>
<string class="p"><local xml:lang="en">and some English here</local></string>
<string class="p"><local xml:lang="en">Some English here</local></string>
</chapter>
<chapter>
<string class="l1"><local xml:lang="fr">Some English translated to French here</local></string>
<string class="p"><local xml:lang="fr">Some other English translated to French here</local></string>
<string class="p"><local xml:lang="fr">and some English translated to French here</local></string>
<string class="p"><local xml:lang="fr">Some English translated to French here</local></string>
</chapter>
<chapter>
<string class="l1"><local xml:lang="de">Some English translated to German here</local></string>
<string class="p"><local xml:lang="de">Some other English translated to German here</local></string>
<string class="another_class"><local xml:lang="de">and some English translated to German here</local></string>
<string class="p"><local xml:lang="de">Some English translated to German here</local></string>
</chapter>
<chapter>
<string class="l1"><local xml:lang="nl">Some English translated to Dutch here</local></string>
<string class="p"><local xml:lang="nl">Some other English translated to Dutch here</local></string>
<string class="p"><local xml:lang="nl">and some English translated to Dutch here<br/>Some English translated to Dutch here</local></string>
</chapter>
</root>

実際のファイルには30の言語と数百のノードを含めることができるため、上記の例は非常に単純化されています。

この例で達成したいのは、英語とフランス語をマージすることです。これらは両方とも同じ量の要素を持ち、すべての属性も同じだからです。すべての属性が一致するわけではないため、フランス語はそのままにする必要があります。要素の量が一致しないため、オランダ語はそのままにする必要があります。

したがって、出力は次のようになります。

<root>
<!-- French has the same amount of elements, and a full sequential match of attributes, so we can merge -->
<chapter>
<string class="l1">
    <local xml:lang="en">Some English here</local>
    <local xml:lang="fr">Some English translated to French here</local>
</string>
<string class="p">
    <local xml:lang="en">Some other English here</local>
    <local xml:lang="fr">Some other English translated to French here</local>
</string>
<string class="p">
    <local xml:lang="en">and some English here</local>
    <local xml:lang="fr">and some English translated to French here</local>
</string>
<string class="p">
    <local xml:lang="en">Some English here</local>
    <local xml:lang="fr">Some English translated to French here</local>
</string>
</chapter>
<!-- German has same amount of elements, but different tag sequence, so we leave it for manual review -->
<chapter>
<string class="l1"><local xml:lang="de">Some English translated to German here</local></string>
<string class="p"><local xml:lang="de">Some other English translated to German here</local></string>
<string class="another_class"><local xml:lang="de">and some English translated to German here</local></string>
<string class="p"><local xml:lang="de">Some English translated to German here</local></string>
</chapter>
<!-- Dutch has same same tag sequence but less elements, so we leave it for manual review-->
<chapter>
<string class="l1"><local xml:lang="nl">Some English translated to Dutch here</local></string>
<string class="p"><local xml:lang="nl">Some other English translated to Dutch here</local></string>
<string class="p"><local xml:lang="nl">and some English translated to Dutch here<br/>Some English translated to Dutch here</local></string>
</chapter>
</root>

英語は常にマスターリファレンスであるため、英語のノード数を比較として使用することで、サイズの異なるノードセットをすでに除外できます。すべての属性値が等しいかどうかを確認する方法がわかりません。

何かアドバイス ?(xslt2を使用)

ありがとう !

4

2 に答える 2

1

XSLT2.0スタイルシートのサンプルは次のとおりです。

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:variable 
  name="master" 
  select="root/chapter[string/local/@xml:lang = 'en']"/>


<xsl:variable 
  name="matches" 
  select="root/chapter[not(string/local/@xml:lang = 'en')]
    [count(string) eq count($master/string)
     and 
      (every $i in (1 to count($master/string))
       satisfies $master/string[$i]/@class eq string[$i]/@class)]"/>

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

<xsl:template match="chapter[. intersect $master]">
  <xsl:copy>
    <xsl:apply-templates select="string"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="string[local/@xml:lang = 'en']">
  <xsl:variable name="pos" select="position()"/>
  <xsl:copy>
    <xsl:apply-templates select="@* | local | $matches/string[$pos]/local"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="chapter[. intersect $matches]"/>

</xsl:stylesheet>

Saxon 9.4でそれを投稿された入力に適用すると、結果が得られます

<root>
   <chapter>
      <string class="l1">
         <local xml:lang="en">Some English here</local>
         <local xml:lang="fr">Some English translated to French here</local>
      </string>
      <string class="p">
         <local xml:lang="en">Some other English here</local>
         <local xml:lang="fr">Some other English translated to French here</local>
      </string>
      <string class="p">
         <local xml:lang="en">and some English here</local>
         <local xml:lang="fr">and some English translated to French here</local>
      </string>
      <string class="p">
         <local xml:lang="en">Some English here</local>
         <local xml:lang="fr">Some English translated to French here</local>
      </string>
   </chapter>
   <chapter>
      <string class="l1">
         <local xml:lang="de">Some English translated to German here</local>
      </string>
      <string class="p">
         <local xml:lang="de">Some other English translated to German here</local>
      </string>
      <string class="another_class">
         <local xml:lang="de">and some English translated to German here</local>
      </string>
      <string class="p">
         <local xml:lang="de">Some English translated to German here</local>
      </string>
   </chapter>
   <chapter>
      <string class="l1">
         <local xml:lang="nl">Some English translated to Dutch here</local>
      </string>
      <string class="p">
         <local xml:lang="nl">Some other English translated to Dutch here</local>
      </string>
      <string class="p">
         <local xml:lang="nl">and some English translated to Dutch here<br/>Some English translated to Dutch here</local>
      </string>
   </chapter>
</root>
于 2012-06-21T10:12:07.620 に答える
0

この変換

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:variable name="vENSignature" select="string-join(/*/*[1]/*/@class, '+')"/>
 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="/*">
  <root>
   <xsl:for-each-group select="chapter"
    group-adjacent="string-join(*/@class, '+') eq $vENSignature">
     <xsl:choose>
       <xsl:when test="current-grouping-key() eq true()">
             <chapter>
              <xsl:apply-templates select="*"/>
            </chapter>
        </xsl:when>
        <xsl:otherwise>
          <xsl:sequence select="current-group()"/>
        </xsl:otherwise>
    </xsl:choose>
   </xsl:for-each-group>
  </root>
 </xsl:template>

 <xsl:template match="chapter/*" >
  <xsl:variable name="vPos" select="position()"/>
  <xsl:copy>
    <xsl:sequence select="@*, current-group()/*[position() = $vPos]/*"/>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

提供されたXMLドキュメントに適用した場合:

<root>
    <chapter>
        <string class="l1">
            <local xml:lang="en">Some English here</local>
        </string>
        <string class="p">
            <local xml:lang="en">Some other English here</local>
        </string>
        <string class="p">
            <local xml:lang="en">and some English here</local>
        </string>
        <string class="p">
            <local xml:lang="en">Some English here</local>
        </string>
    </chapter>
    <chapter>
        <string class="l1">
            <local xml:lang="fr">Some English translated to French here</local>
        </string>
        <string class="p">
            <local xml:lang="fr">Some other English translated to French here</local>
        </string>
        <string class="p">
            <local xml:lang="fr">and some English translated to French here</local>
        </string>
        <string class="p">
            <local xml:lang="fr">Some English translated to French here</local>
        </string>
    </chapter>
    <chapter>
        <string class="l1">
            <local xml:lang="de">Some English translated to German here</local>
        </string>
        <string class="p">
            <local xml:lang="de">Some other English translated to German here</local>
        </string>
        <string class="another_class">
            <local xml:lang="de">and some English translated to German here</local>
        </string>
        <string class="p">
            <local xml:lang="de">Some English translated to German here</local>
        </string>
    </chapter>
    <chapter>
        <string class="l1">
            <local xml:lang="nl">Some English translated to Dutch here</local>
        </string>
        <string class="p">
            <local xml:lang="nl">Some other English translated to Dutch here</local>
        </string>
        <string class="p">
            <local xml:lang="nl">and some English translated to Dutch here
                <br/>Some English translated to Dutch here
            </local>
        </string>
    </chapter>
</root>

必要な正しい結果を生成します。

<root>
   <chapter>
      <string class="l1">
         <local xml:lang="en">Some English here</local>
         <local xml:lang="fr">Some English translated to French here</local>
      </string>
      <string class="p">
         <local xml:lang="en">Some other English here</local>
         <local xml:lang="fr">Some other English translated to French here</local>
      </string>
      <string class="p">
         <local xml:lang="en">and some English here</local>
         <local xml:lang="fr">and some English translated to French here</local>
      </string>
      <string class="p">
         <local xml:lang="en">Some English here</local>
         <local xml:lang="fr">Some English translated to French here</local>
      </string>
   </chapter>
   <chapter>
            <string class="l1">
                  <local xml:lang="de">Some English translated to German here</local>
            </string>
            <string class="p">
                  <local xml:lang="de">Some other English translated to German here</local>
            </string>
            <string class="another_class">
                  <local xml:lang="de">and some English translated to German here</local>
            </string>
            <string class="p">
                  <local xml:lang="de">Some English translated to German here</local>
            </string>
      </chapter>
   <chapter>
            <string class="l1">
                  <local xml:lang="nl">Some English translated to Dutch here</local>
            </string>
            <string class="p">
                  <local xml:lang="nl">Some other English translated to Dutch here</local>
            </string>
            <string class="p">
                  <local xml:lang="nl">and some English translated to Dutch here
                <br/>Some English translated to Dutch here
            </local>
            </string>
      </chapter>
</root>

説明

  1. --の「signature」プロパティを定義して使用します。これは、その子の属性値のchapterシーケンスです。class

  2. すべてのchapter要素は、それらの署名が「英語の署名」と等しいかどうかに基づいてグループ化されます。

  3. chapter署名が「英語の署名」と等しいグループ内の要素をマージします。

  4. chapter他のグループの要素を変更せずにコピーします。

于 2012-06-21T12:12:19.657 に答える