Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transform XML using XSLT in JAVA

Tags:

java

xml

xslt

saxon

I have an example in Java using XSLT 3.0 to merge 2 xml files (personne1 , personne2) using XSLT 3.0 (xsltfilePersonnes.xsl).

I m using Saxon 9.8 (version for XSLT 3.0). Tried so far :

in command line I run this command line :

C:\test2>java -jar saxon-he-9.8.0-1.jar personne1.xml xsltFilePersonnes.xsl -o:resultFile.xml

it run without error and the fileResult was as expected it merge the two files(personne1 and personne2) in the resultfile.xml, but when I run java main class I got this error :

Recoverable error on line 1 column 39 of file:C:\test2\xsltFilePersonnes.xsl:
  SXXP0003: Error reported by XML parser:
  file:C:\test2\xsltFilePersonnes.xsl<Line 1, Column 39>
: XML-20180: (Error) User Supplied NodeFactory returned a Null Pointer.: Invalid URI for stylesheet: file:C:test2\xsltFilePersonnes.xsl

any help is appreciated I m learning Xslt , thank you guys.

personne1.xml :

<personnes>
  <personne>
    <name>aaa</name>
    <age>10</age>
    <adress>aaaaaa</adress>
  </personne>

  <personne>
    <name>bbb</name>
    <age>10</age>
    <adress>aaaaaa</adress>
  </personne>

  <personne>
    <name>ccc</name>
    <age>20</age>
    <adress>cccccc</adress>
  </personne>

  <personne>
    <name>ddd</name>
    <age>10</age>
    <adress>cccccc</adress>
  </personne>


</personnes>

personne2.xml:

<?xml version="1.0" encoding="UTF-8"?>
<personnes>
  <personne>

    <id>1111</id>
    <quantity>1100</quantity>
  </personne>

  <personne>

     <id>2222</id>
     <quantity>2200</quantity>
  </personne>

  <personne>

    <id>3333</id>
    <quantity>3300</quantity>
  </personne>

  <personne>

    <id>4444</id>
    <quantity>4400</quantity>
  </personne>

  <personne>

    <id>5555</id>
    <quantity>5500</quantity>
  </personne>
</personnes>

xsltfilePersonnes.xsl:

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

     <xsl:variable name="personne2"
        select="document('file:test2\personne2.xml')" />
    <xsl:accumulator name="pos" as="xs:integer" initial-value="0">
        <xsl:accumulator-rule match="personnes" select="0"/>
        <xsl:accumulator-rule match="personnes/personne" select="$value + 1"/>
    </xsl:accumulator>

    <xsl:mode use-accumulators="pos"/>    

    <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/*">
    <xsl:copy>
        <xsl:merge>
            <xsl:merge-source select="personne">
                <xsl:merge-key select="accumulator-before('pos')"/>
            </xsl:merge-source>
            <xsl:merge-source for-each-item="$personne2" select="personnes/personne">
                <xsl:merge-key select="accumulator-before('pos')"/>
            </xsl:merge-source>
            <xsl:merge-action>
                <xsl:copy>
                    <xsl:copy-of
                      select="current-merge-group()[2]/id, name, current-merge-group()[2]/quantity, age, adress"/>
                </xsl:copy>
            </xsl:merge-action>
        </xsl:merge>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

main java :

public static void main (String [] args) throws ParserConfigurationException, SAXException, IOException, TransformerException {

  Source input  = new StreamSource("file:\test2\personne1.xml");
  Source xsl    = new StreamSource("file:\test2\filexsltFilePersonnes.xsl");
  Result output = new StreamResult(new File("file:\test2\resultFile.xml")); 
    TransformerFactory factory =new  net.sf.saxon.TransformerFactoryImpl();
        //TransformerFactory.newInstance();
    Transformer transformer = factory.newTransformer(xsl);
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    transformer.transform(input, output);

  }
like image 282
Omar B. Avatar asked Oct 17 '25 09:10

Omar B.


1 Answers

If you want to use StreamSource(String systemId) then a valid local absolute file URI would look something like: new StreamSource("file:///C:/test2/xsltFilePersonnes.xsl").

But I think running your Java code in a certain folder (e.g. C:\test2) and then using relative URIs like new StreamSource("xsltFilePersonnes.xsl") should work as well.

Saxonica also has JAXP samples for 9.8 online here.

like image 176
Martin Honnen Avatar answered Oct 19 '25 23:10

Martin Honnen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!