объединение и восстановление содержимого узлов на основе значений атрибутов - PullRequest
1 голос
/ 02 ноября 2011

У меня есть XML-файл, который содержит следующую разметку

 <xml>
   <content relationship="regula">
       **<source attribute1="RSC1985s5c1" attribute2="6(17)"/>**
       <target attribute1="LRC1985s5c1" attribute1="6(17)1"/>
   </content>

   <content relationship="translation-of">
       **<source attribute1="RSC1985s5c1" attribute2="6(17)"/>**
       <target attribute1="LRC1985s5c4" attribute2="6(17)1"/>
   </content>

   <content relationship="translation-of">
       **<source attribute1="RSC1985s5c2" attribute2="7(17)"/>**
       <target attribute1="LRC1985s5c2" attribute2="7(17)"/>
    </content>

     <content relationship="translation-of">
         **<source attribute1="RSC1985s5c1" attribute2="6(17)"/>**
           <target attribute1="LRC1985s5c6" attribute2="6(17)2"/>
     </content>

   </xml>

То, что я хочу, это объединить содержимое узлов в один новый узел, если значения attribute1 и attrbite2 исходных узлов равны. Таким образом, вывод должен быть как

   <xml>
    <transformed relationship="merged">
          <source attribute1="RSC1985s5c1" attribute2="6(17)"/>
          <target attribute1="LRC1985s5c1" attribute2="6(17)1"/>
          <target attribute1="LRC1985s5c4" attribute2="6(17)1"/>
          <target attribute1="LRC1985s5c6" attribute2="6(17)2"/>
    </transformed>

      <transformed relationship="non-merged">
          <source attribute1="RSC1985s5c2" attribute2="7(17)"/>
           <target attribute1="LRC1985s5c2" attribute2="7(17)"/>
    </transformed>
   </xml>

Итак, первые два узла имеют значения источника attribute1 и attribute2, равные друг другу, поэтому я объединил их как новый узел. Третий узел в источнике не совпадает с другими, поэтому я выводил это отдельно. Я попытался использовать цикл foreach, но не смог найти правильную работу. Благодарим Вас за помощь, если мы сможем добиться с помощью соответствия шаблонов.

Любые узлы содержимого с таким же атрибутом дочернего узла "источник" должны быть сгруппированы независимо от их расположения. Отношение будет изменено на «объединено» для слитых и не слитых элементов, оно будет «не объединено»

1 Ответ

1 голос
/ 02 ноября 2011

Это может быть достигнуто с помощью Muenchian Grouping

Поскольку вам необходимо сопоставить два отдельных атрибута элемента source , вам может понадобиться использовать объединенный ключ, например

<xsl:key name="dupes" 
  match="content/source" 
  use="concat(@attribute1, '|', @attribute2)" />

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

Обычно, чтобы соответствовать первому элементу в каждомгруппа, вы можете сделать это

<xsl:apply-templates select="content/source
   [generate-id() = 
    generate-id(key('dupes', concat(@attribute1, '|', @attribute2))[1])]" />

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

<xsl:apply-templates select="content/source
   [generate-id() = 
      generate-id(key('dupes', concat(@attribute1, '|', @attribute2))[1])]
      [count(key('dupes', concat(@attribute1, '|', @attribute2))) > 1]" />

Вот полный XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:key name="dupes" match="content/source" use="concat(@attribute1, '|', @attribute2)"/>

   <xsl:template match="/xml">
      <xsl:copy>
         <transformed relationship="merged">
            <xsl:apply-templates select="content/source[generate-id() = generate-id(key('dupes', concat(@attribute1, '|', @attribute2))[1])][count(key('dupes', concat(@attribute1, '|', @attribute2))) &gt; 1]"/>
         </transformed>
         <transformed relationship="non-merged">
            <xsl:apply-templates select="content/source[generate-id() = generate-id(key('dupes', concat(@attribute1, '|', @attribute2))[1])][count(key('dupes', concat(@attribute1, '|', @attribute2))) = 1]"/>
         </transformed>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="source">
      <xsl:copy-of select="."/>
      <xsl:copy-of select="key('dupes', concat(@attribute1, '|', @attribute2))/following-sibling::target[1]"/>
   </xsl:template>
</xsl:stylesheet>

При применении к вашему примеру XML, выводится следующее

<xml>
   <transformed relationship="merged">
      <source attribute1="RSC1985s5c1" attribute2="6(17)"/>
      <target attribute1="LRC1985s5c1" attribute2="6(17)1"/>
      <target attribute1="LRC1985s5c4" attribute2="6(17)1"/>
      <target attribute1="LRC1985s5c6" attribute2="6(17)2"/>
   </transformed>
   <transformed relationship="non-merged">
      <source attribute1="RSC1985s5c2" attribute2="7(17)"/>
      <target attribute1="LRC1985s5c2" attribute2="7(17)"/>
   </transformed>
</xml>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...