可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I want to pass Map object as parameter in XSLT 2.0 version and i want to retrieve the Map object data under XSLT 2.0 file using Saxon-HE.
I googled a lot and found Retrieving hashmap values in XSLT
link which completely matches according to my need but i am getting exception such as
Static error in {map:get($mapData,'1')} in expression in xsl:variable/@select on line 23 column 94 of transformer.xslt: XPST0017: Cannot find a 2-argument function named {http://ns.saxonica.com/map}get().
I don't know where i am doing mistake.
These are the my files. SexsonDemo.java
public static void transform(String xmlFile, String xslFile) throws TransformerException, TransformerConfigurationException { TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(new StreamSource(new File(xslFile))); Map<String,String> mapData = new HashMap<String,String>(); mapData.put("1", "188 E 6th Street"); transformer.setParameter("mapData", mapData); transformer.transform(new StreamSource(new File(xmlFile)), new StreamResult(System.out)); }
transformer.xsl
xmlns:map="http://ns.saxonica.com/map" exclude-result-prefixes="map" > <xsl:variable name="mapData"/> <xsl:variable name="addressData" select="map:get($mapData,'1')"/>
at below line i getting exception map:get($mapData,'1')

回答1:
As for reading XDM maps in XSLT, see https://xsltfiddle.liberty-development.net/6qVRKwZ which has three examples
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:map="http://www.w3.org/2005/xpath-functions/map" xmlns:array="http://www.w3.org/2005/xpath-functions/array" exclude-result-prefixes="#all" expand-text="yes" version="3.0"> <xsl:param name="mapData" as="map(xs:string, xs:string)" select="map { '1' : '188 E 6th Street' }"/> <xsl:mode on-no-match="shallow-copy"/> <xsl:output method="html" indent="yes" html-version="5"/> <xsl:template match="/"> <html> <head> <title>.NET XSLT Fiddle Example</title> </head> <body> <h1>XPath 3.1 map example</h1> <section> <h2>function call syntax</h2> <p><code>$mapData('1')</code>: <code>{$mapData('1')}</code></p> </section> <section> <h2>map:get</h2> <p><code>map:get($mapData, '1')</code>: <code>{map:get($mapData, '1')}</code></p> </section> <section> <h2><code>?</code> operator</h2> <p><code>$mapData?('1')</code>: <code>{$mapData?('1')}</code></p> </section> </body> </html> </xsl:template> </xsl:stylesheet>
For setting this parameter from your Java code, consider using the Saxon s9api http://saxonica.com/html/documentation9.8/using-xsl/embedding/s9api-transformation.html to run Saxon and then you can use hhttp://saxonica.com/html/documentation9.8/javadoc/net/sf/saxon/s9api/Xslt30Transformer.html#setStylesheetParameters-java.util.Map- to pass in an XdmMap constructed from your Java Map with http://saxonica.com/html/documentation9.8/javadoc/net/sf/saxon/s9api/XdmMap.html#makeMap-java.util.Map-.
Short Java sample is
public static void MapExample() throws SaxonApiException { Processor processor = new Processor(false); XsltExecutable executable = processor.newXsltCompiler().compile(new StreamSource("sheet.xsl")); Xslt30Transformer transformer = executable.load30(); Map<String,String> mapData = new HashMap<String,String>(); mapData.put("1", "188 E 6th Street"); HashMap<QName, XdmValue> parameters = new HashMap<>(); parameters.put(new QName("mapData"), XdmMap.makeMap(mapData)); transformer.setStylesheetParameters(parameters); transformer.applyTemplates(new StreamSource("input1.xml"), transformer.newSerializer(System.out)); System.out.println(); }
回答2:
I think that the namespace URI {http://ns.saxonica.com/map} was used during some early Saxon experiments in implementing maps, long before they were part of the W3C specification: see https://www.saxonica.com/html/documentation9.4/extensions/map.html
That specification was long ago superseded by the W3C map functions, which are in namespace http://www.w3.org/2005/xpath-functions/map.
That's part of your problem. The other part is how to convert a Java map to an XDM map. You can do this in Saxon 9.8/9.9 using the static method XdmMap.makeMap(java.util.Map). It might be easier in some cases to pass in a string containing a JSON representation of the map, and then parse it within the stylesheet using the parse-json() function.