Home > OS >  XSL1.0 : Selecting specific elements in repeating
XSL1.0 : Selecting specific elements in repeating

Time:10-27

Having an XML like this:

<categories>
    <request type="this request is B and O">
        <list name="B"/>
        <list name="O"/>
    </request>  
    <request type="this request is N only">
        <list name="N"/>
    </request>
    <request type="this request is O and E">
        <list name="O"/>
        <list name="E"/>
    </request>
    <request type="this request is O and G">
        <list name="O"/>
        <list name="G"/>
    </request>
    <request type="this request is N and E">
        <list name="N"/>
        <list name="E"/>
    </request>
        <request type="this request is E only">
        <list name="E"/>
    </request>
    <request type="this request is B only">
        <list name="B"/>
    </request>
    <request type="this request is B and N">
        <list name="N"/>
        <list name="B"/>
    </request>
</categories>

I tried like below:

<xsl:template name="simplified">
    <xsl:for-each select="categories/request[child::list/@name = 'B'] | categories/request[child::list/@name = 'O'] | categories/request[child::list/@name = 'N']">
        <fo:block>
            <xsl:value-of select="@type"/>
        </fo:block>
    </xsl:for-each>
</xsl:template>

The rule is:

  • Repeat after all requests, where its children of type <list> will be only with name B, O, or N;
  • In case one <request> element has one list with @name "B" and one list with @name "O" or "N", it should be added in repeating;
  • In case one <request> element has one list with @name "N" or "O", but the previous or next list element (under the same <request> ) has @name "G" or "E", it should NOT be added in repeating.

Now I am receiving the following results:

this request is B and O
this request is N only
this request is O and E
this request is O and G
this request is N and E
this request is B only
this request is B and N

I need to receive the below correct result:

this request is B and O
this request is N only
this request is B only
this request is B and N

How can I update my repeating template for xsl1.0?

CodePudding user response:

I find it very difficult to understand your description. It seems you want to do:

XSLT 1.0

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>

<xsl:template match="/categories">
    <xsl:for-each select="request[not(list[contains('GE', @name)])]">
        <xsl:value-of select="@type"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

or - if you prefer whitelisting instead of blacklisting:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>

<xsl:template match="/categories">
    <xsl:for-each select="request[not(list[not(contains('BON', @name))])]">
        <xsl:value-of select="@type"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>
  • Related