2013-12-05 3 views
0

После прочтения 5 часов здесь на stackoverflow и на других сайтах я не смог создать решение для своей проблемы. Множество описанных проблем звучит знакомо с моим решением. Но, к несчастью, я не смог добавить его ко мне.группировка/перемещение узлов с одинаковым атрибутом

Мой исходный файл XML выглядит следующим образом:

<document> 
    <page> 
    <block> 
     <line> 
     <span string="String1" bottom="12" /> 
     </line> 
    </block> 
    <block> 
     <line> 
     <span string="String2" bottom="12" /> 
     </line> 
    </block> 
    <block> 
     <line> 
     <span string="String3" bottom="12" /> 
     </line> 
    </block> 
    <block> 
     <line> 
     <span string="String4" bottom="20" /> 
     </line> 
    </block> 
    <block> 
     <line> 
     <span string="String5" bottom="20" /> 
     </line> 
    </block> 
    <block> 
     <line> 
     <span string="String6" bottom="30" /> 
     </line> 
    </block> 
    </page> 
    <page> 
    <block> 
     <line> 
     <span string="String10" bottom="20" /> 
     </line> 
    </block> 
    <block> 
     <line> 
     <span string="String11" bottom="20" /> 
     </line> 
    </block> 
    <block> 
     <line> 
     <span string="String12" bottom="25" /> 
     </line> 
    </block> 
    </page> 
</document> 

В результате я пытаюсь достичь с помощью XSLT выглядит следующим образом:

<document> 
    <page> 
    <block> 
     <line> 
     <span string="String1" bottom="12" /> 
     <span string="String2" bottom="12" /> 
     <span string="String3" bottom="12" /> 
     </line> 
    </block> 
    <block> 
     <line> 
     <span string="String4" bottom="20" /> 
     <span string="String5" bottom="20" /> 
     </line> 
    </block> 
    <block> 
     <line> 
     <span string="String6" bottom="30" /> 
     </line> 
    </block> 
    </page> 
    <page> 
    <block> 
     <line> 
     <span string="String10" bottom="20" /> 
     <span string="String11" bottom="20" /> 
     </line> 
    </block> 
    <block> 
     <line> 
     <span string="String12" bottom="25" /> 
     </line> 
    </block> 
    </page> 
</document> 

Теперь мои thougts в натуральном Speek:

  • идентифицировать элемент блока
  • сравнить :

    following-sibling::*[1]/line/span/@bottom = self::line/span[last()]/@bottom" 
    
  • если они равны - скопировать span из «вниз» в качестве последнего узла под фактическим block/line узла
  • удалить «старый» span узел
  • удалить весь родственный, состоят только из //block/line без каких-либо далее span

И это одна плохая попытка найти рабочую XSLT:

<?xml version="1.0" encoding="UTF8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="xml" indent="yes"/> 

    <!-- Identity - copy all other data--> 
    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 


    <xsl:template match="//block/line"> 
     <line> 
     <xsl:apply-templates select="node()|@*" /> 
     <xsl:if test="parent::block/following-sibling::*[1]/line/span/@bottom = span[last()]/@bottom"> 
      <xsl:copy-of select="parent::block/following-sibling::*[1]/line/span" /> 
      <xsl:apply-templates select="parent::block/following-sibling::*[1]/*" /> 
     </xsl:if> 
     </line> 
    </xsl:template> 


</xsl:stylesheet> 

Надеюсь, что кто-то может помочь! :-)

+0

вы определенно застряли на 1 XSLT (как это намного проще с xslt2 :-) –

+0

Normaly Я использую 'xmlstarlet' из командной строки, чтобы перевести или проверить некоторые вещи. К несчастью, он не поддерживает xslt2. Но не стоит использовать 'xsltproc', который может обрабатывать xslt2. Поэтому, когда кто-то придумает решение xslt2, я также буду рад. :-) – JANetworkX

+0

xsltproc только xslt1 –

ответ

1

В XSLT2 (или 3) вы должны использовать xsl: для каждой группы, но в XSLT1 вы можете сделать то же самое с «Muenchian Grouping» (используя ключ, чтобы избежать эксплуатационных затрат на проверку братьев и сестер на каждой итерации)

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

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

<xsl:key name="b" match="page//span" 
    use="concat(generate-id(ancestor::page[1]),' ',@bottom)"/> 

<xsl:template match="*"> 
<xsl:copy> 
    <xsl:copy-of select="@*"/> 
    <xsl:apply-templates/> 
</xsl:copy> 
</xsl:template> 

<xsl:template match="page"> 
<page> 
    <xsl:for-each select=".//span[generate-id()= 
      generate-id(key('b', 
      concat(generate-id(ancestor::page[1]),' ',@bottom))[1])]"> 
    <block> 
    <line> 
    <xsl:apply-templates select="key('b', 
        concat(generate-id(ancestor::page[1]),' ',@bottom))"/> 
    </line> 
    </block> 
    </xsl:for-each> 
</page> 
</xsl:template> 

</xsl:stylesheet> 
+0

Thx David. Ваше решение работает как чары. Похоже, я должен разогреться с xslt2. :-) – JANetworkX

+0

Ups - скажет: теперь настало время не разогреваться с xslt2. Кажется, я должен лечь спать. ;-) – JANetworkX

Смежные вопросы