Фильтровать и группировать в XSLT

Я пытаюсь отфильтровать данные, а затем сгруппировать их с помощью XSLT. Вот мой XML

    <?xml version="1.0" encoding="UTF-8"?>
<AccumulatedOutput>
    <root>
        <Header>
            <Add>true</Add>
            <Name>Subscriber</Name>
            <Value>SAC</Value>
        </Header>
    </root>
    <root>
        <Header>
            <Add>true</Add>
            <Name>System</Name>
            <Value>CBP</Value>
        </Header>
    </root>
    <root>
        <Header>
            <Add>false</Add>
            <Name>Subscriber</Name>
            <Value>SAC</Value>
        </Header>
    </root>
</AccumulatedOutput>

Что я хочу сделать, так это эту группу, основанную на Header/Name, и удалить группу, в которой Header/Add является ложным. Итак, в приведенном выше примере будут созданы две группы (одна для Name=Subscriber, а другая для Name=System), но поскольку первая группа (с Name=Subscriber) содержит Add=false, я хочу игнорировать это, и мой вывод должен иметь только один узел, как показано ниже.

<?xml version = "1.0" encoding = "UTF-8"?>
<root>
    <Header>
        <Name>System</Name>
        <Value>CBP</Value>
        <Add>true</Add>
    </Header>
</root> 

Я пытался использовать группу по методу, но не могу понять, как ее отфильтровать. Будет большим подспорьем, если кто-то может дать мне несколько указателей

Спасибо


person Kapil    schedule 30.03.2015    source источник
comment
Выберите либо XSLT 1.0, либо 2.0, а не оба варианта одновременно.   -  person michael.hor257k    schedule 30.03.2015
comment
Я не против использовать любой из них для решения этой проблемы, поэтому использовал оба   -  person Kapil    schedule 30.03.2015
comment
Что вы хотите делать с группами, содержащими более одного элемента, вы хотите их как-то объединить или вывести только все элементы?   -  person Martin Honnen    schedule 30.03.2015
comment
Выводить только все элементы, но если пропустить ту группу, для которой Add=false.   -  person Kapil    schedule 30.03.2015


Ответы (2)


В XSLT 2.0 вы можете сделать следующее:

<xsl:template match="/AccumulatedOutput">
    <root>
        <xsl:for-each-group select="root/Header" group-by="Name">
            <xsl:if test="not(current-group()/Add='false')">
                <xsl:copy-of select="current-group()"/>
            </xsl:if>
        </xsl:for-each-group>
    </root>
</xsl:template>
person michael.hor257k    schedule 30.03.2015

Нет явных условных инструкций XSLT:

<xsl:template match="/*">
    <root>
        <xsl:for-each-group group-by="Name" select=
        "root/Header[for $n in string(Name)
                      return every $h in /*/root/Header[Name eq $n] 
                                     satisfies not($h/Add eq 'false')]">
              <xsl:sequence select="current-group()"/>
        </xsl:for-each-group>
    </root>
</xsl:template>
person Dimitre Novatchev    schedule 05.04.2015