2012-06-21 7 views
1

немного борется, чтобы заставить следующее работать: я пытаюсь объединить переведенные узлы, но поскольку иногда между наборами узлов существуют незначительные различия, я не могу сделать это только с завязанными глазами и требуется ручная проверка. Тем не менее, в то же время мне нравится сохранять мою жизнь простой, поэтому я хочу автоматизировать фронт настолько, насколько это возможно. Ниже приводится пример:объединяет узел только в том случае, если все атрибуты равны

Фактические файлы могут содержать 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> 

английский всегда мастер ссылки, так что я уже могу исключить nodesets, которые разностной размера, используя английский язык nodecount как сравнение, просто не имеют ни малейшего представления о как проверить, равны ли все значения атрибутов.

Любые советы? (с использованием xslt2)

Спасибо!

ответ

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. Определим и использовать "подпись" свойство chapter - то есть последовательность class значения атрибута его дочерних элементов.

  2. Мы группируем все элементы chapter на основании того, соответствует ли их подпись «английской подписи».

  3. Мы объединяем элементы chapter в группе, чья подпись соответствует «английской подписи».

  4. Мы копируем без изменений элементы chapter другой группы.

+0

Dimitre, вы сделали какое-то редактирование, которое, как я думаю, больше не приводит к требуемому результату, поскольку '' будет копировать дочерние элементы в настоящее время сгруппированные элементы 'chapter' на выходе (т. е. элементы' string'), в то время как вы, вероятно, хотите '' скопировать элементы 'chapter'. –

+0

@MartinHonnen: Спасибо, что заметили это - исправлено. –

+0

Спасибо, оба! @Martin: Я окончательно использовал решение Dimitres, так как это позволило мне использовать его также с «вложенными главами» после некоторой модификации. Довольно уверен, что это возможно и с вашим, но просто не знало, как использовать переменные в правильном порядке. – Wokoman

1

Вот пример XSLT 2.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> 
Смежные вопросы