У меня есть следующий XML




У меня есть следующий шаблон freemarker, в котором элементы xml внедряются как "элементы".

[<#list elements as element>{"primeLineNo":"${element.OS_LINESTATUS.@LINENUMBER}","poLineStatusInfos":[{"poLineStatus":"${element.OS_LINESTATUS.@STATUSCODE}"<#if element.OS_LINESTATUS.@QUANTITY??>,"poLineStatusQuantity":{"measurementValue":"${element.OS_LINESTATUS.@QUANTITY}","unitOfMeasure":"EA"}}]}<#sep>,]}]}}

Но это не удается сделать в третьей строке, поскольку отсутствует атрибут quantity, хотя я поставил условие if. Почему условие if не работает?

Следующая трассировка стека

==> element.OS_LINESTATUS.@QUANTITY  [in template "suman-xml-to-xml-    orderrequestxform/xml-aggregation/linestatus.ftl" at line 4, column 331]

----
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 ("~" означает вложенность): - Failed at: ${element.OS_LINESTATUS.@QUANTITY} [в шаблоне "suman-xml-to- xml-orderrequestxform/xml-aggregation/linestatus.ftl" в строке 4, столбец 329]

Трассировка стека Java (для программистов):

freemarker.core.NonStringException: [... Exception message was already  printed; see it above ...]
at freemarker.core.EvalUtil.coerceModelToString(EvalUtil.java:390)
at freemarker.core.Expression.evalAndCoerceToString(Expression.java:82)
at freemarker.core.DollarVariable.accept(DollarVariable.java:41)
at freemarker.core.Environment.visit(Environment.java:324)
at freemarker.core.MixedContent.accept(MixedContent.java:54)
at freemarker.core.Environment.visitByHiddingParent(Environment.java:345)
at freemarker.core.ConditionalBlock.accept(ConditionalBlock.java:48)
at freemarker.core.Environment.visit(Environment.java:324)
at freemarker.core.MixedContent.accept(MixedContent.java:54)
at freemarker.core.Environment.visitByHiddingParent(Environment.java:345)
at freemarker.core.IteratorBlock$IterationContext.executeNestedBlockInner(IteratorBlock.java:268)
at freemarker.core.IteratorBlock$IterationContext.executeNestedBlock(IteratorBlock.java:220)
at freemarker.core.IteratorBlock$IterationContext.accept(IteratorBlock.java:194)
at freemarker.core.Environment.visitIteratorBlock(Environment.java:572)
at freemarker.core.IteratorBlock.acceptWithResult(IteratorBlock.java:78)
at freemarker.core.IteratorBlock.accept(IteratorBlock.java:64)
at freemarker.core.Environment.visit(Environment.java:324)
at freemarker.core.MixedContent.accept(MixedContent.java:54)
at freemarker.core.Environment.visit(Environment.java:324)
at freemarker.core.Environment.process(Environment.java:302)
at freemarker.template.Template.process(Template.java:325)
at example.aggregation.XmlElementAggregator.output(XmlElementAggregator.java:93)
at example.aggregation.XmlElementAggregator.aggregate(XmlElementAggregator.java:58)
at example.aggregation.XmlElementAggregator.visitAfter(XmlElementAggregator.java:45)
at org.milyn.delivery.sax.SAXHandler.visitAfter(SAXHandler.java:389)
at org.milyn.delivery.sax.SAXHandler.endElement(SAXHandler.java:204)
at org.milyn.delivery.SmooksContentHandler.endElement(SmooksContentHandler.java:96)
at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source)
at org.apache.xerces.parsers.AbstractXMLDocumentParser.emptyElement(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.milyn.delivery.sax.SAXParser.parse(SAXParser.java:76)
at org.milyn.delivery.sax.SmooksSAXFilter.doFilter(SmooksSAXFilter.java:86)
at org.milyn.delivery.sax.SmooksSAXFilter.doFilter(SmooksSAXFilter.java:64)
at org.milyn.Smooks._filter(Smooks.java:526)
at org.milyn.Smooks.filterSource(Smooks.java:482)
at example.TransformerBuilder.transform(TransformerBuilder.java:66)
at example.TransformAggregation.main(TransformAggregation.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

Suman Shil

Ответов: 1

Ответы (1)

Условие #if работает, потому что вы спрашиваете, существует ли element.OS_LINESTATUS.@QUANTITY, который существует, поскольку это набор результатов размером 0. Вместо этого используйте element.OS_LINESTATUS.@QUANTITY[0]??. Так вот в чем хитрость DOM-обертки FreeMarker, что даже запросы, которые ничего не находят, что-то возвращают. Вот почему такой результат является #list-able, и, что более важно, может быть контекстом для дальнейших запросов XPath (например, element.maybeMissingElement.child никогда не терпит неудачу, просто иногда дает пустой набор результатов).

2022 WebDevInsider