xmlxsltxslt-2.0saxonxslt-3.0

Filtering arrays from Saxon XSLT API in Java?


I have this xml:

<?xml version="1.0" encoding="UTF-8"?>
<Document>
    <tag-one>
        <tag-two>
            <tag-three>
                <tag-four>
                    <tag-five>
                        <tag-six>
                            <tag-seven>
                                <tag-eight>
                                    <tag-nine>
                                        <id-tag>valid_id</id-tag>
                                    </tag-nine>
                                </tag-eight>
                            </tag-seven>
                        </tag-six>
                    </tag-five>
                </tag-four>
            </tag-three>
        </tag-two>
        <tag-two>
            <tag-three>
                <tag-four>
                    <tag-five>
                        <tag-six>
                            <tag-seven>
                                <tag-eight>
                                    <tag-nine>
                                        <id-tag>invalid_id-invalid_kg</id-tag>
                                    </tag-nine>
                                </tag-eight>
                            </tag-seven>
                        </tag-six>
                    </tag-five>
                </tag-four>
            </tag-three>
        </tag-two>
    </tag-one>
</Document>

I'm trying to build an XSLT file that filters out the tag-two elements if their corresponding id-tag is contained in a list

<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        exclude-result-prefixes="#all"
        version="3.0">

    <xsl:param name="invalidIds"/>

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


    <xsl:template
            match="tag-two[contains($invalidIds, tag-three/tag-four/tag-five//*[local-name()='id-tag'])]">
    </xsl:template>

</xsl:transform>

I'm passing the invalidIds as an arraylist in java code using the saxon library:

List<String> idList = Arrays.asList("invalid_id-invalid_kg");
// omitted rest of the code for brevity
// Map.of(new QName("invalidIds"), new XdmAtomicValue(idList.toString()))

When I printed out the invalidIds value in xslt, I got this: [invalid_id-invalid_kg].

The problem is that it filters both tag-two because it looks like the contains methods act as a "String" contains, not an "Array" contains, meaning that "valid_id" matches the condition... Do you have any idea how I can fix this?


Solution

  • Use https://www.saxonica.com/html/documentation12/javadoc/net/sf/saxon/s9api/XdmValue.html#makeSequence(java.lang.Iterable) on your Java List e.g. Map.of(new QName("invalidIds"), XdmValue.makeSequence(idList)).

    And the template should be

    <xsl:template match="tag-two[$invalidIds = tag-three/tag-four/tag-five//id-tag]"/>