2011-11-01 2 views
1

У меня есть файл 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 loop, но не мог нормально работать. Оцените свою помощь, если мы сможем добиться этого, используя совпадение с шаблоном.

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

+0

@_atif: Должны ли быть объединены любые два узла контента с «общими» дочерними элементами? Связаны ли только два соседних узла контента? Что, если более двух узлов «контента» имеют «общие» элементы? Должен ли атрибут 'relation' действительно теряться в результате слияния? Слишком много вещей не ясно в этом вопросе. Пожалуйста, отредактируйте и предоставите недостающую информацию. –

+0

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

+0

@_atif: Ну, это хорошо сказать в комментарии, но это относится к вопросу - пожалуйста, отредактируйте свой вопрос и предоставить эту информацию. Кроме того, вы не ответили на мой вопрос, какой должен быть ожидаемый идентификатор вывода, более чем два узла должны быть объединены - пожалуйста, укажите такой пример в своем вопросе. Я определенно не хочу догадываться о вещах, о которых вы, возможно, даже не думали ... –

ответ

1

Это может быть достигнуто путем Muenchian Группировка

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

<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])]" /> 

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

<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> 
Смежные вопросы