2013-06-25 9 views
1

У меня есть выбор XML (отредактированный)выбор XSLT возвращение следующих братьев

<items>     
    <item id="00100537" label="A/137i r" lcn="005417713" notes="A/137-160"/> 
    <item id="00100538" label="A/137i v" lcn="" notes=""/> 
    <item id="00100539" label="A/137ii r" lcn="" notes=""/> 
    <item id="00100540" label="A/137ii v" lcn="" notes=""/> 
    <item id="00100678" label="A/159iii v" lcn="" notes=""/> 
    <item id="00100679" label="A/159iv r" lcn="" notes=""/> 
    <item id="00100680" label="A/159iv v" lcn="" notes=""/> 
    <item id="00100681" label="A/160i r" lcn="" notes=""/> 
    <item id="00100682" label="A/160i v" lcn="" notes=""/> 
    <item id="00100683" label="A/160ii r" lcn="" notes=""/> 
    <item id="00100684" label="A/160ii v" lcn="" notes=""/> 
    <item id="00100685" label="A/160iii r" lcn="" notes=""/> 
    <item id="00100686" label="A/160iii v" lcn="" notes=""/> 
    <item id="00100687" label="A/161i r" lcn="005417714" notes="A/161-182"/> 
    <item id="00100688" label="A/161i v" lcn="" notes=""/> 
    <item id="00100819" label="A/182ii v" lcn="" notes=""/> 
    <item id="00100820" label="A/182iii r" lcn="" notes=""/> 
    <item id="00100821" label="A/182iii v" lcn="" notes=""/> 
    <item id="00100822" label="A/183i r" lcn="005417715" notes="A/183-218"/> 
    <item id="00100823" label="A/183i v" lcn="" notes=""/> 
    <item id="00100975" label="A/216iii r" lcn="" notes=""/> 
    <item id="00100976" label="A/216iii v" lcn="" notes=""/> 
    <item id="00100977" label="A/217i r" lcn="" notes=""/> 
    <item id="00100978" label="A/217i v" lcn="" notes=""/> 
    <item id="00100979" label="A/217ii r" lcn="" notes=""/> 
    <item id="00100980" label="A/217ii v" lcn="" notes=""/> 
    <item id="00100981" label="A/218i r" lcn="" notes=""/> 
    <item id="00100982" label="A/218i v" lcn="" notes=""/> 
    <item id="00100983" label="A/218ii r" lcn="" notes=""/> 
    <item id="00100984" label="A/218ii v" lcn="" notes=""/> 
    <item id="00100985" label="A/219i r" lcn="005417716" notes="A/219-248"/> 
    <item id="00100986" label="A/219 v" lcn="" notes=""/> 
    <item id="00100987" label="A/219ii r" lcn="" notes=""/> 
    <item id="00101061" label="A/248 r" lcn="" notes=""/> 
    <item id="00101062" label="A/248 v" lcn="" notes=""/> 
</items> 

Я хочу, чтобы иметь возможность получить все следующие узлы из данного LCN до следующего LCN.

Если я начинаю с lcn = '005417714', я знаю, что есть 4 следующих узла.

Но когда я пытаюсь сделать что-то вроде этого

<xsl:for-each select="/items/item[@lcn='005417714']/following-sibling::*"> 

я получаю все следующие братьев и сестер. Как я могу получить все следующие братья и сестры перед следующим непустым атрибутом lcn? Так получить только 4 следующих братьев и сестер? благодаря

+0

XSLT 1.0 или 2.0? –

+0

XSLT 1.0, но я не пробовал 2.0. Я мог бы дать решение от 2.0, чтобы посмотреть, работает ли оно. – user2075215

ответ

2

В XSLT 2.0 вы можете использовать <xsl:for-each-group> и, в частности, его group-starting-with атрибут для итерации по группам элементов, начиная с непустого lcn. В XSLT 1.0 есть различные возможности. Самый простой подход будет что-то вроде

<xsl:for-each select="/items/item[@lcn='005417714']"> 
    <xsl:for-each select="following-sibling::*[ 
     generate-id(preceding-sibling::item[@lcn != ''][1]) 
     = generate-id(current())]"> 
    </xsl:for-each> 
</xsl:for-each> 

, которая рассматривает все следующие брат и сестра нашей целевой элемент и выбирает тех, чьи ближайший предшествующий-родственный с непустыми lcn атрибутом является целевым элементом.

Если вы хотите перебрать более все «разделы», а не просто нацеливать один конкретный, тогда подход сгруппировки по ключевым словам suggested by hr_117 будет более эффективным.

4

С XSLT-1,0 вы можете попробовать что-то вроде этого решения на основе ключа: (только, чтобы показать, как она могла бы работать)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:key name="kfItem" match="item[@lcn = '']" 
     use="generate-id(preceding-sibling::item[@lcn != ''][1])"/> 

    <xsl:template match="/*"> 
     <items> 
      <xsl:apply-templates select="item[@lcn != '']"/> 
     </items> 
    </xsl:template> 

    <xsl:template match="item"> 
     <lcn lcn="{@lcn}"> 
      <xsl:copy-of select="."/> 
      <xsl:copy-of select="key('kfItem', generate-id())"/> 
     </lcn> 
    </xsl:template> 
</xsl:stylesheet> 

, который будет генерировать следующий вывод:

<items> 
    <lcn lcn="005417713"> 
    <item id="00100537" label="A/137i r" lcn="005417713" notes="A/137-160"/> 
    <item id="00100538" label="A/137i v" lcn="" notes=""/> 
    <item id="00100539" label="A/137ii r" lcn="" notes=""/> 
    <item id="00100540" label="A/137ii v" lcn="" notes=""/> 
    <item id="00100678" label="A/159iii v" lcn="" notes=""/> 
    <item id="00100679" label="A/159iv r" lcn="" notes=""/> 
    <item id="00100680" label="A/159iv v" lcn="" notes=""/> 
    <item id="00100681" label="A/160i r" lcn="" notes=""/> 
    <item id="00100682" label="A/160i v" lcn="" notes=""/> 
    <item id="00100683" label="A/160ii r" lcn="" notes=""/> 
    <item id="00100684" label="A/160ii v" lcn="" notes=""/> 
    <item id="00100685" label="A/160iii r" lcn="" notes=""/> 
    <item id="00100686" label="A/160iii v" lcn="" notes=""/> 
    </lcn> 
    <lcn lcn="005417714"> 
    <item id="00100687" label="A/161i r" lcn="005417714" notes="A/161-182"/> 
    <item id="00100688" label="A/161i v" lcn="" notes=""/> 
    <item id="00100819" label="A/182ii v" lcn="" notes=""/> 
    <item id="00100820" label="A/182iii r" lcn="" notes=""/> 
    <item id="00100821" label="A/182iii v" lcn="" notes=""/> 
    </lcn> 
    <lcn lcn="005417715"> 
    <item id="00100822" label="A/183i r" lcn="005417715" notes="A/183-218"/> 
    <item id="00100823" label="A/183i v" lcn="" notes=""/> 
    <item id="00100975" label="A/216iii r" lcn="" notes=""/> 
    <item id="00100976" label="A/216iii v" lcn="" notes=""/> 
    <item id="00100977" label="A/217i r" lcn="" notes=""/> 
    <item id="00100978" label="A/217i v" lcn="" notes=""/> 
    <item id="00100979" label="A/217ii r" lcn="" notes=""/> 
    <item id="00100980" label="A/217ii v" lcn="" notes=""/> 
    <item id="00100981" label="A/218i r" lcn="" notes=""/> 
    <item id="00100982" label="A/218i v" lcn="" notes=""/> 
    <item id="00100983" label="A/218ii r" lcn="" notes=""/> 
    <item id="00100984" label="A/218ii v" lcn="" notes=""/> 
    </lcn> 
    <lcn lcn="005417716"> 
    <item id="00100985" label="A/219i r" lcn="005417716" notes="A/219-248"/> 
    <item id="00100986" label="A/219 v" lcn="" notes=""/> 
    <item id="00100987" label="A/219ii r" lcn="" notes=""/> 
    <item id="00101061" label="A/248 r" lcn="" notes=""/> 
    <item id="00101062" label="A/248 v" lcn="" notes=""/> 
    </lcn> 
</items> 
+0

вот так вот путь. Вы можете сделать это полностью в xpath, но ключ имеет гораздо лучшую производительность. У меня был 4 МБ (а не огромный файл) с совпадением шаблонов родного брата с использованием xpath --- и он шел медленно. Я перешел к ключу, подобному этому, и теперь мгновенно пробегает взгляд. – Paulb