Skip to Content
author's profile photo Former Member
Former Member

Call an XSLT mapping from Java or Graphical Mapping

Is there API or other tool to invoke an XSLT mapping from within a UDF(graphical mapping) function or a java mapping? I have a need to take a particular branch of an XML document, remove the namespaces, and then escape it, and fill it in a target node. The escaping is not a problem, but I need a way to remove namespaces from only a single branch of the XML tree.

So something like this:

<ns0:PurchaseOrderArchive>
  <ns0:Header>
    <ns0:Line>
...
    </ns0:Line>
  </ns0:Header>
<ns0:PurchaseOrderArchive>

Needs to become this:

<ns0:PurchaseOrderEscaped>
  <Header>
    <Line>
    </Line>
  </Header>
<ns0:PurchaseOrderEscapted>
 

Passing the node a string to a UDF that invokes an xslt is the first approach I have tried. If I include an XSLT in a jar locally, I can invoke it using the following code:

public enum XSLTransformer implements XMLTransformer {
  REMOVE_NAMESPACES("xsl/RemoveNamespaces.xsl");
  Transformer transformer;
  private XSLTransformer(String xsltName) {

    URIResolver xsltLoader = new URIResolver() {
      @Override
      public Source resolve(String href, String base) 
             throws TransformerException {
        try {
          InputStream is = ClassLoader.getSystemResourceAsStream(href);;
          return new StreamSource(is, href);
        } catch (Exception ex) {
          throw new TransformerException(ex);
        }
      }
    };

    TransformerFactory tFactory = TransformerFactory.newInstance();
    tFactory.setURIResolver(xsltLoader);
    try {
      Source xsltSource = xsltLoader.resolve(xsltName, "");
      transformer = tFactory.newTransformer(xsltSource);
    } catch (TransformerConfigurationException e) {
      throw new AssertionError(e);
    } catch (TransformerException e) {
      throw new AssertionError(e);
    }
  }

  @Override
  public String tranform(String inString) throws XMLTransformException {
    StringWriter outputWriter = new StringWriter();
    Result outputTarget = new StreamResult(outputWriter);
    Source inSource = new StreamSource(new StringReader(inString));
    try {
      transformer.transform(inSource, outputTarget);
    } catch (TransformerException e) {
      throw new XMLTransformException(e);
    }
    return outputWriter.toString();
  }
}


Note the path to the XSLT in the jar is "xsl/RemoveNamespaces.xsl"

If I load this to PI as an imported archive, the resolution of the xsl no longer works and I get a FileNotFoundException. It would see that PI does some repackages of the jar contents.

Any thoughts about how something this this can be accomplished?

Add comment
10|10000 characters needed characters exceeded

1 Answer

  • Posted on Mar 06, 2017 at 03:52 PM
    -2

    Hi Thomas,

    Create a new XSD / Message Type from the xml with your desired Node: <ns0:PurchaseOrderEscaped> and add an additional graphical mapping step in your Operation Mapping which will pass values from Source <ns0:PurchaseOrderArchive> to Target <ns0:PurchaseOrderEscaped>. Rest of the nodes and fields in this new XSD / Message Type would be identical to the Original Target XSD/ Message Type.

    Regards,

    Nabendu.

    Add comment
    10|10000 characters needed characters exceeded