迭代XSLT中Java扩展函数返回的ArrayList(Saxon)
我有一个使用XSLT执行XML映射的程序。我使用的是Saxon-HE-9.7库。我还在XSLT中使用自反扩展函数 XSLT调用返回迭代XSLT中Java扩展函数返回的ArrayList(Saxon),java,xslt,saxon,Java,Xslt,Saxon,我有一个使用XSLT执行XML映射的程序。我使用的是Saxon-HE-9.7库。我还在XSLT中使用自反扩展函数 XSLT调用返回ArrayList 得克萨斯州 我只得到列表中的sinlge记录,它是executeQueryMultiResult返回的列表的最后一条记录 我想存储并迭代列表中的所有元素?首先,我有点惊讶,当您迭代abc/company[@type='product']时,xsl:for each的主体在任何方面都不依赖于当前选择的公司。这意味着该循环的每次迭代都将产生完全相同
ArrayList
得克萨斯州
我只得到列表中的sinlge记录,它是executeQueryMultiResult返回的列表的最后一条记录
我想存储并迭代列表中的所有元素?首先,我有点惊讶,当您迭代
abc/company[@type='product']
时,xsl:for each
的主体在任何方面都不依赖于当前选择的公司。这意味着该循环的每次迭代都将产生完全相同的输出
在默认Java到XPath转换下,ArrayList
应该转换为XPath序列,但Java映射不会转换为XPath映射;它们需要作为外部对象进行访问
查看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());
}
}
public void testlistofmap(){
试一试{
处理器p=新处理器(真);
XsltCompiler c=p.newXsltCompiler();
字符串s=“\n”+
“\n”+
“\n”+
“\n”+
“\n”+
“\n”+
“\n”+
“\n”+
"";
XsltTransformer t=c.compile(新的StreamSource(新的StringReader)).load();
StringWriter out=新建StringWriter();
序列化程序ser=p.newSerializer(out);
t、 设置目的地(ser);
t、 setInitialTemplate(新的QName(“主”));
t、 transform();
assertTrue(out.toString().equals(“2星期三”);
}捕获(萨克森例外e1){
失败(e1.getMessage());
}
}
其中,扩展函数jf:getListOfMaps()是:
公共静态列表getListOfMaps(字符串x,字符串y){
Map m=新的HashMap();
m、 付诸表决(“星期一”、“星期一”);
m、 付诸表决(“星期二”、“星期二”);
m、 put(x,y);
Map n=新的HashMap();
m、 卖出(“一月”、“一月”);
m、 卖出(“二月”、“二月”);
列表=新的ArrayList();
增加(m);
列表。添加(n);
退货清单;
}
测试表明Saxon的行为符合规范:Java映射列表被转换为外部对象的XPath序列,其中外部对象是Java映射的包装器,允许使用底层Java方法
我在Saxon9.9上运行了这个程序(9.7不再受支持)
我建议您尝试生成一个repo,通过使用一个伪存根替换扩展函数来简化问题,该伪存根具有任何人都可以运行测试的相同签名
我还建议你确切地告诉我们你的环境是什么。我有点困惑,你说你使用的是Saxon HE,因为Saxon HE不支持自反扩展函数。Try@ajeethingh-Try,它不起作用。他支持自反扩展函数吗?我想它们只在商业PE和EE版本中受支持。count($list)返回1,而查询返回8条记录。谢谢您的帮助。实际上,问题在于我的ExtensionFunction实现类。我已经把这个问题以不同的方式重新提出了
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());
}
}
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;
}