我是“smooks和freemarker”的新手。我想要访问xml文档中的元素。我在访问xml元素时遇到此异常。我正在发送我的代码。
Exception:-
------------
For "${...}" content: Expected a string or something automatically convertible to string (number, date or boolean), but this evaluated to a sequence+hash (wrapper: f.e.dom.NodeListModel):
==> employee["first_name"] [in template "free-marker-template" at line 1, column 84]
----
Tip: This XML query result can't be used as string because for that it had to contain exactly 1 XML node, but it contains 0 nodes. That is, the constructing XML query has found no matches.
----
----
FTL stack trace ("~" means nesting-related):
- Failed at: ${employee["first_name"]} [in template "free-marker-template" at line 1, column 82]
----
Java stack trace (for programmers):
----
freemarker.core.NonStringException: [... Exception message was already printed; see it above ...]
at freemarker.core.EvalUtil.coerceModelToString(EvalUtil.java:381)
at freemarker.core.Expression.evalAndCoerceToString(Expression.java:82)
at freemarker.core.DollarVariable.accept(DollarVariable.java:40)
at freemarker.core.Environment.visit(Environment.java:312)
The following are versions
java version : "1.7.0_45"
freemarker : 2.3.22
smooks : 1.6
javacode:-
-----------
package test;
import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.net.URI;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.milyn.Smooks;
import org.milyn.SmooksException;
import org.milyn.container.ExecutionContext;
import org.milyn.event.report.HtmlReportGenerator;
import org.milyn.io.StreamUtils;
import org.milyn.payload.StringResult;
import org.xml.sax.SAXException;
public class SmooksExample {
public SmooksExample() {
// TODO Auto-generated constructor stub
}
protected static void runSmooksNew() throws IOException, SAXException, SmooksException {
try {
Long stTime = System.currentTimeMillis();
System.out.println(stTime + "==" + new Date());
Writer xmlResultWriter = new BufferedWriter(new FileWriter(new File("C:\\Files\\SmookExample\\output_sax.dat")));
transCustomerCSV(new File("C:\\Files\\emp_namespace.xml"), xmlResultWriter);
Long edTime = System.currentTimeMillis();
System.out.println(edTime + "==" + (edTime-stTime) + "===="+ new Date());
String times = String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes(edTime-stTime),
TimeUnit.MILLISECONDS.toSeconds(edTime-stTime) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(edTime-stTime))
);
System.out.println(times);
} finally {
//smooks.close();
}
}
public static void transCustomerCSV(File csvSourceReader, Writer xmlResultWriter) throws IOException, SAXException {
File f = new File("C:/TEMPLATES/smooks-config.xml");
URI u = f.toURI();
Smooks smooks = new Smooks(u.getPath());
ExecutionContext ec = smooks.createExecutionContext();
smooks.filterSource(ec, new StreamSource(csvSourceReader), new StreamResult(xmlResultWriter));
}
/**
* @param args
*/
public static void main(String[] args) throws IOException, SAXException, SmooksException {
System.out.println("\n\n");
System.out.println("==============Message In==============");
SmooksExample.runSmooksNew();
System.out.println("======================================\n");
}
}
Smooks-config.xml
--------------------
<smooks-resource-list xmlns:ftl="http://www.milyn.org/xsd/smooks/freemarker-1.1.xsd" xmlns:core="http://www.milyn.org/xsd/smooks/smooks-core-1.3.xsd" xmlns:jb="http://www.milyn.org/xsd/smooks/javabean-1.2.xsd" xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd">
<params>
<param name="stream.filter.type">SAX</param>
<param name="default.serialization.on">false</param>
</params>
<core:namespaces>
<core:namespace prefix="empl" uri="http://www.example.com/employees"/>
</core:namespaces>
<resource-config selector="employee,first_name">
<resource>org.milyn.delivery.DomModelCreator</resource>
</resource-config>
<ftl:freemarker applyOnElement="first_name">
<ftl:template><!--<#ftl ns_prefixes={"empl":"http://www.example.com/employees"}>${employee["@id"]},${employee["first_name"]}-->
</ftl:template>
</ftl:freemarker>
</smooks-resource-list>
sample data xml file name: emp_namespace.xml:-
--------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<empl:employees xmlns:empl="http://www.example.com/employees">
<empl:employee id="1">
<empl:first_name>Bill</empl:first_name>
<empl:last_name>Adams</empl:last_name>
<empl:age>25</empl:age>
<empl:hire_date>12-06-1995</empl:hire_date>
<empl:title>Java programmer</empl:title>
<empl:DateCreated>
<empl:Year>1980</empl:Year>
<empl:Month>01</empl:Month>
<empl:Day>01</empl:Day>
</empl:DateCreated>
<empl:DateCompleted>
<empl:Year>1981</empl:Year>
<empl:Month>02</empl:Month>
<empl:Day>02</empl:Day>
</empl:DateCompleted>
</empl:employee>
<empl:employee id="2">
<empl:first_name>Mary</empl:first_name>
<empl:last_name>Jones</empl:last_name>
<empl:age>32</empl:age>
<empl:hire_date>22-09-2001</empl:hire_date>
<empl:title>Sales manager</empl:title>
<empl:DateCreated>
<empl:Year>1982</empl:Year>
<empl:Month>03</empl:Month>
<empl:Day>03</empl:Day>
</empl:DateCreated>
<empl:DateCompleted>
<empl:Year>1983</empl:Year>
<empl:Month>04</empl:Month>
<empl:Day>04</empl:Day>
</empl:DateCompleted>
</empl:employee>
</empl:employees>
答案 0 :(得分:0)
在ns_prefixes
中,您指定FTL中使用的名称空间前缀,该名称空间前缀与XML中使用的名称空间前缀无关。 FreeMarker并不关心XML中的实际前缀是什么,它只关心命名空间URL。因此,既然你已经声明了empl
前缀,那么你也必须使用FTL(比如empl\:employee.empl\:first_name
- 有点尴尬,因为:
必须被转义)。但由于您主要访问该单个命名空间,因此我建议将该命名空间URL声明为默认值:
<#ftl ns_prefixes={"D": "http://www.example.com/employees"}>
然后您不必添加前缀:
${employee.first_name}
(注意,在这里我假设在Smooks中数据模型根是文档元素。我不知道这是否属实,但无论如何,就XML名称空间而言,这就是它的工作原理。此外,你在XML中有多个employee
- s,因此上面的多个匹配不起作用,但这是另一个主题。)