Search code examples
javaxmlxsltsaxon

I can select tags from documents as parameter using SAXON XSLT


Here is an example of my code. I want to use multiple documents while I transform my XMLs document. So, I pass them as parameters to my XSLT file. The issue is I am not able to select XML tags from those parameters documents.

Java Code

public class MultipleDocument {

    @Test
    public void parser_multiple_document() throws SaxonApiException, IOException {
        final Path path = Paths.get("src/test/resources/Transformations/multipleDocs.xslt");

        final StreamSource xsltFile =  new StreamSource(path.toFile());
        final Processor processor = new Processor(false);
        final DocumentBuilder documentBuilder = processor.newDocumentBuilder();

        final DocZipMocks docZipMocks = new DocZipMocks();


        final Iterable<XdmNode> zipMocks = Stream.of("<resEvento xmlns:xsd="http://www.w3.org/2001/XMLSchema"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" versao="1.01"    xmlns="http://www.portalfiscal.inf.br/nfe"><cOrgao>00</cOrgao><CNPJ>123456789</CNPJ><chNFe>000000000000000000000000</chNFe><dhEvento>2000-02-06T04:05:57-03:00</dhEvento><tpEvento>00000</tpEvento><nSeqEvento>0</nSeqEvento><xEvento>Registro de Passagem Automatico MDF-e com CT-e</xEvento><dhRecbto>2000-02-06T04:05:57-03:00</dhRecbto><nProt>000000000000</nProt></resEvento>")
                .map(this.createDocument(documentBuilder))
                .collect(Collectors.toList());

        final XsltCompiler compiler = processor.newXsltCompiler();
        compiler.setParameter(new QName("docs"),new XdmValue(zipMocks));

        final XsltExecutable stylesheet = compiler.compile(xsltFile);
        final Xslt30Transformer transformer = stylesheet.load30();

        final ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
        final Writer writer = new OutputStreamWriter(byteStream,"UTF-8");
        final Serializer out = processor.newSerializer(writer);

        transformer.transform(new StreamSource(new StringReader("<dummmy><my>ass</my></dummmy>")), out);

        final String string = new StringBuilder(byteStream.toString("UTF-8")).toString();

        System.out.println(string);
    }

    private Function<String,XdmNode> createDocument(DocumentBuilder documentBuilder){
        return doc -> {
            try {
                return documentBuilder.build(new StreamSource(new StringReader(doc)));
            } catch (SaxonApiException e) {
                throw new RuntimeException(e);
            }
        };
    }
}

#XML

<resEvento xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" versao="1.01"
    xmlns="http://www.portalfiscal.inf.br/nfe">
    <cOrgao>00</cOrgao>
    <CNPJ>123456789</CNPJ>
    <chNFe>000000000000000000000000</chNFe>
    <dhEvento>2000-02-06T04:05:57-03:00</dhEvento>
    <tpEvento>00000</tpEvento>
    <nSeqEvento>0</nSeqEvento>
    <xEvento>Registro de Passagem Automatico MDF-e com CT-e</xEvento>
    <dhRecbto>2000-02-06T04:05:57-03:00</dhRecbto>
    <nProt>000000000000</nProt>
</resEvento>

XSLT CODE

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <xsl:output method="text" indent="no"
                omit-xml-declaration="yes" />
     <xsl:param name="docs" as="document-node()*" />


    <xsl:template match="/">

        <xsl:for-each select="$docs">
            <xsl:value-of select="resEvento/CNPJ/text()"/>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

What am I doing wrong? Why can't I select a specific tag from the parameter doc?


Solution

  • Thank you guys I got it working fine I solved setting right the namespace

    OR

    I could simply use *:tag-name works as well

    SOLUTION

        <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="3.0"
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:xs="http://www.w3.org/2001/XMLSchema"
                    xmlns:xnf="http://www.portalfiscal.inf.br/nfe"
                    xmlns:fn="http://www.w3.org/2005/xpath-functions">
        <xsl:output method="text" indent="no"
                    omit-xml-declaration="yes" />
         <xsl:param name="docs" as="document-node()*" />
    
    
        <xsl:template match="/">
    
            <xsl:for-each select="$docs">
                <xsl:value-of select="xnf:resEvento/xnf:CNPJ/text()"/>
            </xsl:for-each>
        </xsl:template>
    </xsl:stylesheet>