在 XSLT(Saxon) 中迭代 Java 扩展函数返回的 ArrayList [英] Iterate ArrayList returned by Java extension function in XSLT(Saxon)
问题描述
我有一个使用 XSLT 执行 XML 映射的程序.我为此使用 Saxon-HE-9.7 库.我也在 XSLT 中使用自反扩展函数.
I have a program to perform XML mapping using XSLT. I'm using Saxon-HE-9.7 library for this. I'm also using reflexive extension functions in XSLT.
XSLT 调用返回 ArrayList
<?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 返回的列表的最后一条记录.
I'm getting only sinlge record in the list which is the last record of the list returned by executeQueryMultiResult.
我想存储和迭代列表中的所有元素?
I want to store and iterate all the elements of the list?
推荐答案
首先,当你迭代 abc/company[@type='product']
时,我有点惊讶xsl:for-each
的主体不以任何方式依赖于当前选定的 company
.这意味着这个循环的每次迭代都会产生完全相同的输出.
Firstly, I'm a bit surprised that when you iterate over abc/company[@type='product']
, the body of the xsl:for-each
doesn't depend in any way on the current selected company
. This means that each iteration of this loop will produce exactly the same output.
在默认的Java-to-XPath转换下,ArrayList
应该被转换成XPath序列,但是java Maps不会被转换成XPath Maps;它们需要作为外部对象访问.
Under the default Java-to-XPath conversions, the ArrayList
should be converted to an XPath sequence, but the java Maps will not be converted to XPath maps; they need to be accessed as external objects.
查看 count($list)
返回什么并检查它是否符合您的期望.
See what count($list)
returns and check that it matches your expectations.
稍后
我无法重现该问题.我是这样测试的:
I am unable to reproduce the problem. I tested it like this:
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() 在哪里:
where the extension function jf:getListOfMaps() is:
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 方法.
The test demonstrates that Saxon is behaving according to the spec: the Java List of Maps is converted to an XPath sequence of external objects, where the external object is a wrapper around the Java Map that allows use of the underlying Java methods.
我在 Saxon 9.9 上运行此程序(不再支持 9.7).
I ran this on Saxon 9.9 (9.7 is no longer supported).
我建议您尝试制作一个重现,通过将您的扩展函数替换为具有任何人都可以运行以进行测试的相同签名的虚拟存根来简化问题.
I suggest you try and produce a repro that simplifies the problem by replacing your extension function with a dummy stub with the same signature that anyone can run for testing.
我还建议您准确地告诉我们您的环境是什么.我有点不明白你说你在使用 Saxon-HE,因为 Saxon-HE 不支持自反扩展函数.
I also suggest you tell us exactly what your environment is. I'm a bit puzzled that you say you are using Saxon-HE, because Saxon-HE doesn't support reflexive extension functions.
这篇关于在 XSLT(Saxon) 中迭代 Java 扩展函数返回的 ArrayList的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!