XSLT search using key when XSLT Source is processed from String to java

I am trying to handle an XSLT search - instead of entering XSLT data as a string instead of a file. Everything works well if I write the modified XSLT as a file and read it again for conversion, but when I treat it as a string, the search does not work.

The method that performs the conversion is as follows.

public static void transform(File inputXmlfile, String outputXmlFileName) throws ParserConfigurationException, SAXException, IOException, TransformerException { DocumentBuilderFactory docBuildFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder parser = docBuildFactory.newDocumentBuilder(); Document document = parser.parse(inputXmlfile); TransformerFactory xformFactory = TransformerFactory.newInstance(); String xsltString="<?xml version=\"1.0\" encoding=\"utf-8\"?>"+ "<xsl:stylesheet version=\"1.0\""+ " xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:c=\"http://myDomain.com/classifications.data\">"+ "<xsl:output method=\"xml\" />"+ "<xsl:key name=\"classification-lookup\" match=\"c:classification\" use=\"c:id\" /> <xsl:template match=\"/\"><listings xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://local.google.com/local_feed.xsd\"><language>en</language><datum>WGS84</datum>" + "<xsl:for-each select=\"BusinessListings/BusinessListing\"><listing><id><xsl:value-of select=\"id\" /></id><xsl:apply-templates /></listing></xsl:for-each></listings></xsl:template><xsl:template match=\"classificationId\"><xsl:variable name=\"currentId\" select=\".\" />" + "<xsl:for-each select=\"document('')\"><category><xsl:value-of select=\"key('classification-lookup',$currentId)/c:description\" /></category></xsl:for-each></xsl:template> <xsl:template match=\"text()\" />" + "<c:classifications><c:classification><c:id>3</c:id><c:description>Abortion Alternatives</c:description></c:classification><c:classification><c:id>4</c:id><c:description>Abortion Providers</c:description>" + "</c:classification><c:classification><c:id>9</c:id><c:description>Abrasives</c:description></c:classification></c:classifications></xsl:stylesheet>"; Transformer transformer = xformFactory.newTransformer(new StreamSource(IOUtils.toInputStream(xsltString))); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); FileOutputStream fileOutputStream = new FileOutputStream(new File(outputXmlFileName)); DOMSource source = new DOMSource(document); Result result = new StreamResult(fileOutputStream); transformer.transform(source, result); fileOutputStream.close(); } 

when I try it as follows (after writing modifiel xsl and reading it)

  Transformer transformer = xformFactory.newTransformer(new StreamSource(xsltFile)); 

it works fine but

  Transformer transformer = xformFactory.newTransformer(new StreamSource(IOUtils.toInputStream(xsltString))); does not process the lookup. 

The input is as shown below

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <BusinessListings vendorId="0" schemaVersion="" fileCreateDate="" xmlns="http://www.myDomain.com"> <BusinessListing> <id>1593469</id> <listingData> <classifications> <classificationId>3</classificationId> <classificationId>9</classificationId> </classifications> </listingData> </BusinessListing> </BusinessListings> 

what could be the problem?

0
source share
2 answers

First, to answer your question, refer to the XSLT 1.0 specification, which explains the use of a zero-length string arg for a function:

Note that a zero-length URI reference is a reference to a document with respect to which a URI reference is permitted; thus the document ("") refers to the root node of the stylesheet; the tree view of the stylesheet is exactly the same as if the XML document containing the stylesheet was the original source document.

Since the source for your stylesheet is a stream in memory, there is no URI for the URI. It works with the file, since it is able to resolve the location of the file and reload it. There might be some way to get this to work with a system identifier or a custom URI resolver, but I think there might be a simpler approach.

Secondly, why do you embed classification data in XSLT? Why not just pass it as a parameter? This seems a lot simpler and will work basically the same, replacing the call to the document ('') with a parameter reference.

0
source

Can you pass a ByteArrayInputStream to a StreamSource? You can initialize this with String.

Sort of:

 ByteArrayInputStream bais = new ByteArrayInputStream(xsltString.getBytes(), "UTF-8"); Transformer transformer = xformFactory.newTransformer( new StreamSource( bais ) ); 
0
source

All Articles