【问题标题】:Retrieving hashmap values in XSLT 2.0 Using Saxon-HE使用 Saxon-HE 在 XSLT 2.0 中检索 hashmap 值
【发布时间】:2018-10-24 10:11:56
【问题描述】:

我想在 XSLT 2.0 版本中将 Map 对象作为参数传递,并且我想使用 Saxon-HE 检索 XSLT 2.0 文件下的 Map 对象数据。

我google了很多,发现Retrieving hashmap values in XSLT

根据我的需要完全匹配的链接,但我遇到了异常,例如

表达式中的 {map:get($mapData,'1')} 出现静态错误 xsl:variable/@select 位于transformer.xslt 的第 23 行第 94 列: XPST0017:找不到名为 {http://ns.saxonica.com/map}get() 的 2 参数函数。

我不知道我在哪里做错了。

这些是我的文件。 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));
  }


转换器.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')"/>

在下面一行我得到异常 map:get($mapData,'1')

【问题讨论】:

标签: java xml xslt-2.0 saxon


【解决方案1】:

关于在 XSLT 中读取 XDM 映射,请参阅https://xsltfiddle.liberty-development.net/6qVRKwZ,其中包含三个示例

<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>

要从您的 Java 代码中设置此参数,请考虑使用 Saxon s9api http://saxonica.com/html/documentation9.8/using-xsl/embedding/s9api-transformation.html 来运行 Saxon,然后您可以使用 hhttp://saxonica.com/html/documentation9.8/javadoc/net/sf/saxon/ s9api/Xslt30Transformer.html#setStylesheetParameters-java.util.Map- 传入一个 XdmMap,该 XdmMap 由您的 Java Map 构造而成,带有 http://saxonica.com/html/documentation9.8/javadoc/net/sf/saxon/s9api/XdmMap.html#makeMap-java.util.Map-

简短的 Java 示例是

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();        
}

【讨论】:

  • 构造函数new XdmMap(java.util.Map) 仅在java.util.MapMap&lt;XdmAtomicValue, XdmValue&gt; 时才有效。如果你想传入Map&lt;String, String&gt;,那么静态makeMap() 方法是更好的选择。
  • 感谢您的回复!标准 Java API 中是否有 XdmMap.makeMap 的等价物?我的问题的另一部分是样式表参数是由其他项目发送的,它们必须包含 Saxon 依赖项才能使用 XdmMap。
  • 如果“标准 Java API”是指 SUN/Oracle JAXP API,那么答案是否定的,它面向 XSLT 1.0,它只支持 XSLT/XPath 1.0 数据类型(嗯,它是关于它支持的内容有点通用,但它是针对 XSLT/XPath 1.0 设计的)。关于依赖关系,我不确定您指的是什么,您的原始示例使用 Java Map/HashMap 并且可以继续使用它,只有在运行转换之前设置参数的部分需要使用XdmMap.makeMap
【解决方案2】:

我认为命名空间 URI {http://ns.saxonica.com/map} 早在它们成为 W3C 规范的一部分之前,就在一些早期的 Saxon 实验中用于实现地图:参见 https://www.saxonica.com/html/documentation9.4/extensions/map.html

该规范早已被 W3C 映射函数所取代,这些函数位于命名空间 http://www.w3.org/2005/xpath-functions/map

这是你的问题的一部分。另一部分是如何将 Java 映射转换为 XDM 映射。您可以在 Saxon 9.8/9.9 中使用静态方法 XdmMap.makeMap(java.util.Map) 执行此操作。在某些情况下,传入包含地图的 JSON 表示形式的字符串,然后使用 parse-json() 函数在样式表中对其进行解析可能会更容易。

【讨论】:

  • 感谢您的回复。给定的信息对我更有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-11
  • 1970-01-01
  • 1970-01-01
  • 2021-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多