java - 迭代 XSLT(Saxon) 中 Java 扩展函数返回的 ArrayList
问题描述
我有一个使用 XSLT 执行 XML 映射的程序。我为此使用 Saxon-HE-9.7 库。我还在 XSLT 中使用自反扩展函数。
XSLT 调用一个 java 函数,该函数返回ArrayList<HashMap<String, String>>
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0" xmlns:SQLService="com.db.SQLService" xmlns:ArrayList="java:java.util.ArrayList" xmlns:HashMap="java.util.HashMap" >
<xsl:output method="xml" indent="yes" />
<xsl:variable name="city">Texas</xsl:variable>
<xsl:variable name="query" select="'Select name, emp_id from employee where city = ?'" />
<xsl:variable name="list" select="SQLService:executeQueryMultiResult($query, $city)" />
<xsl:template match="/">
<test>
<xsl:for-each select="abc/company[@type='product']">
<employee>
<xsl:attribute name="details">
<xsl:value-of select="$list" />
</xsl:attribute>
</employee>
</xsl:for-each>
</test>
</xsl:template>
</xsl:stylesheet>
我只得到列表中的单条记录,这是executeQueryMultiResult 返回的列表的最后一条记录。
我想存储和迭代列表的所有元素?
解决方案
首先,我有点惊讶的是,当您迭代 时abc/company[@type='product']
,的主体xsl:for-each
不会以任何方式依赖于当前 selected company
。这意味着此循环的每次迭代都将产生完全相同的输出。
在默认的 Java-to-XPath 转换下,ArrayList
应该转换为 XPath 序列,但 java Maps 不会转换为 XPath maps;它们需要作为外部对象访问。
查看count($list)
返回的内容并检查它是否符合您的期望。
之后
我无法重现该问题。我是这样测试的:
public void testListOfMaps() {
try {
Processor p = new Processor(true);
XsltCompiler c = p.newXsltCompiler();
String s = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<xsl:stylesheet version=\"3.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n" +
" xmlns:jf=\"java:s9apitest.TestReflexionHelper\">\n" +
" <xsl:output method=\"text\" />\n" +
" <xsl:template name='main'>\n" +
" <xsl:variable name=\"theList\" select=\"jf:getListOfMaps('Weds', 'Wednesday')\" />\n" +
" <xsl:value-of select=\"count($theList)\" />\n" +
" <xsl:value-of select=\"Q{java:java.util.Map}get($theList[1], 'Weds')\" />\n" +
" </xsl:template>\n" +
"</xsl:stylesheet>";
XsltTransformer t = c.compile(new StreamSource(new StringReader(s))).load();
StringWriter out = new StringWriter();
Serializer ser = p.newSerializer(out);
t.setDestination(ser);
t.setInitialTemplate(new QName("main"));
t.transform();
assertTrue(out.toString().equals("2Wednesday"));
} catch (SaxonApiException e1) {
fail(e1.getMessage());
}
}
其中扩展函数 jf:getListOfMaps() 是:
public static List<Map<String, String>> getListOfMaps(String x, String y) {
Map<String, String> m = new HashMap<>();
m.put("Mon", "Monday");
m.put("Tues", "Tuesday");
m.put(x, y);
Map<String, String> n = new HashMap<>();
m.put("Jan", "January");
m.put("Feb", "February");
List<Map<String, String>> list = new ArrayList<>();
list.add(m);
list.add(n);
return list;
}
测试表明 Saxon 的行为符合规范:Java 映射列表被转换为外部对象的 XPath 序列,其中外部对象是 Java 映射的包装器,允许使用底层 Java 方法。
我在 Saxon 9.9 上运行了这个(不再支持 9.7)。
我建议您尝试生成一个简化问题的重现,方法是用任何人都可以运行以进行测试的相同签名的虚拟存根替换您的扩展函数。
我还建议您确切地告诉我们您的环境是什么。您说您使用的是 Saxon-HE,我有点不解,因为 Saxon-HE 不支持反身扩展功能。
推荐阅读
- php - 调整所有移动设备的 DIV 表大小
- eclipse - 如何获取我在 Eclipse 的代码编辑器中选择的代码的行号
- image - 如何在 Flutter 中制作带有价格的图像框
- coordinates - 59-60秒坐标问题
- c# - 识别 C# Selenium 中身份验证弹出窗口的外观
- php - 如何在php中对数组进行substr?
- file - 在文件或文件夹名称的末尾添加或替换当前日期
- angular - 自动触发 Azure 发布管道
- android - 在三星 S9+ 上配置 AMediaCodec 解码器实例时出错
- javascript - 为什么 chrome 扩展 javascript ajax 调用在调用 yii2 操作时不返回成功的 json 数据?