简体   繁体   English

xslt返回以下兄弟姐妹的选择

[英]xslt return selection of following siblings

I have a selection of XML (edited) 我可以选择XML(已编辑)

<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>

I want to be able to get all following nodes from a given lcn before the next lcn. 我希望能够从下一个lcn之前的给定lcn中获取所有后续节点。

If I start at lcn='005417714' I know there are 4 following nodes. 如果我从lcn ='005417714'开始,我知道下面有4个节点。

But when I try and do something like this 但是当我尝试做这样的事情时

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

I get all following-siblings. 我得到所有跟随的兄弟姐妹。 How can I get all following-siblings before the next non-empty lcn attribute? 如何获得下一个非空lcn属性之前的所有后续兄弟姐妹? So retrieve only the 4 following siblings? 因此,仅检索以下4个兄弟姐妹? thanks 谢谢

With xslt-1.0 you may try something like this key based solution: (Only to show how it could work) 使用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>

Which will generate the following output: 这将生成以下输出:

<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>

In XSLT 2.0 you could use <xsl:for-each-group> and in particular its group-starting-with attribute to iterate over groups of elements starting with a non-empty lcn . 在XSLT 2.0中,您可以使用<xsl:for-each-group> ,尤其是其group-starting-with属性来遍历以非空lcn开头的元素组。 In XSLT 1.0 there are various possibilities. 在XSLT 1.0中,存在多种可能性。 The simplest approach would be something like 最简单的方法是

<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>

which examines all the following siblings of our target item and selects those whose nearest preceding-sibling with a non-empty lcn attribute is the target item. 它检查目标项目的以下所有同级项,并选择那些具有非空lcn属性的最接近的先前同级项的目标项。

If you want to iterate over all the "sections" rather than just targetting one specific one then the key-based grouping approach suggested by hr_117 would be more efficient. 如果要遍历所有 “节”而不是仅针对某个特定节,则hr_117建议的基于密钥的分组方法将更加有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM