这是一个jboss保险丝项目
我有这种情况,其中一个文件有1个带有多个子记录的XML。我需要拆分子记录并使用XSLT将其转换为多个XML 。 示例XML顺序(输入):
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
</catalog>
&#13;
我有这个XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<!-- TODO: Auto-generated template -->
<xsl:for-each select="catalog/cd">
<xsl:result-document href="file{position()}.xml">
<document>
<xsl:copy-of select="current()"/>
</document>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
&#13;
BLUEPRINT.xml(CAMEL ROUTE)
<route id="_route1">
<from id="_from1" uri="file:work/in"/>
<log id="_log1" message="${body}"/>
<loop id="_loop1">
<xpath>count(/catalog/cd)</xpath>
<to id="_to1" uri="xslt:file:C:\Users\a638030\workspace\splitxml\data\order1.xsl"/>
<log id="_log2" message="${body}"/>
</loop>
</route>
&#13;
当我运行此路线时,它表示错误如下:
[xt) thread #2 - file://work/in] _route1 INFO <?xml version="1.0" encoding="UTF-8"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
</catalog>
[xt) thread #2 - file://work/in] XPathBuilder INFO Created default XPathFactory com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl@4b4289ed
[xt) thread #2 - file://work/in] DefaultErrorHandler ERROR Failed delivery for (MessageId: ID-MC0WKB0C-60902-1513777570783-0-1 on ExchangeId: ID-MC0WKB0C-60902-1513777570783-0-2). Exhausted after delivery attempt: 1 caught: org.apache.camel.builder.xml.InvalidXPathExpression: Invalid xpath: count(/catalog/cd). Reason: javax.xml.xpath.XPathExpressionException: com.sun.org.apache.xpath.internal.XPathException: Can not convert #NUMBER to a NodeList!
Message History
---------------------------------------------------------------------------------------------------------------------------------------
RouteId ProcessorId Processor Elapsed (ms)
[_route1 ] [_route1 ] [file://work/in ] [ 270]
[_route1 ] [_log1 ] [log ] [ 7]
[_route1 ] [_loop1 ] [loop[xpath{XPath: count(/catalog/cd)}] ] [ 224]
Stacktrace
---------------------------------------------------------------------------------------------------------------------------------------
org.apache.camel.builder.xml.InvalidXPathExpression: Invalid xpath: count(/catalog/cd). Reason: javax.xml.xpath.XPathExpressionException: com.sun.org.apache.xpath.internal.XPathException: Can not convert #NUMBER to a NodeList!
at org.apache.camel.builder.xml.XPathBuilder.doInEvaluateAs(XPathBuilder.java:916)
at org.apache.camel.builder.xml.XPathBuilder.evaluateAs(XPathBuilder.java:780)
at org.apache.camel.builder.xml.XPathBuilder.evaluate(XPathBuilder.java:750)
at org.apache.camel.builder.xml.XPathBuilder.evaluate(XPathBuilder.java:165)
at org.apache.camel.processor.LoopProcessor.process(LoopProcessor.java:64)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:468)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:196)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:121)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:196)
at org.apache.camel.component.file.GenericFileConsumer.processExchange(GenericFileConsumer.java:454)
at org.apache.camel.component.file.GenericFileConsumer.processBatch(GenericFileConsumer.java:226)
at org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:190)
at org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:175)
at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:102)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.xml.xpath.XPathExpressionException: com.sun.org.apache.xpath.internal.XPathException: Can not convert #NUMBER to a NodeList!
at com.sun.org.apache.xpath.internal.jaxp.XPathExpressionImpl.evaluate(XPathExpressionImpl.java:204)
at org.apache.camel.builder.xml.XPathBuilder.doInEvaluateAs(XPathBuilder.java:898)
... 22 more
Caused by: com.sun.org.apache.xpath.internal.XPathException: Can not convert #NUMBER to a NodeList!
at com.sun.org.apache.xpath.internal.objects.XObject.error(XObject.java:711)
at com.sun.org.apache.xpath.internal.objects.XObject.nodelist(XObject.java:457)
at com.sun.org.apache.xpath.internal.jaxp.XPathExpressionImpl.getResultAsType(XPathExpressionImpl.java:364)
at com.sun.org.apache.xpath.internal.jaxp.XPathExpressionImpl.eval(XPathExpressionImpl.java:110)
at com.sun.org.apache.xpath.internal.jaxp.XPathExpressionImpl.evaluate(XPathExpressionImpl.java:191)
... 23 more
&#13;
你可以帮我解决这个问题,还是有其他方法可以解决这个问题?
场景:我有这种情况,其中一个文件有1个带有多个子记录的XML。我需要拆分子记录并使用XSLT将其转换为多个XML(在JBOSS FUSE中)
答案 0 :(得分:1)
谢谢你的帮助@ noMad17。
(BLUEPRINT.XML)使用ActiveMQ路由:
<route id="_route1">
<from id="_from1" uri="file:work/in"/>
<log id="_log1" message="${body}"/>
<split id="_split1">
<xpath>/catalog/cd</xpath>
<log id="_log3" message="split data : ${body}"/>
<to id="_to1" uri="xslt:file:C:\Users\a638030\workspace\Scenario5\data\order.xsl"/>
<log id="_log2" message="After XSLT : ${body}"/>
<to id="_to2" pattern="InOnly" uri="activemq:queue:OrderDetails"/>
</split>
</route>
&#13;
XML INPUT:
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<cd >
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
</catalog>
&#13;
XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:element name="catalog">
<xsl:element name="cd">
<xsl:copy-of select="/*[local-name()='cd']/*"/>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
&#13;
输出MSG IN ACTIVEMQ:
Message 1 :
<?xml version="1.0" encoding="UTF-8"?><catalog><cd><title>Empire Burlesque</title><artist>Bob Dylan</artist><country>USA</country><company>Columbia</company><price>10.90</price><year>1985</year></cd></catalog>
Message 2:
<?xml version="1.0" encoding="UTF-8"?><catalog><cd><title>Hide your heart</title><artist>Bonnie Tyler</artist><country>UK</country><company>CBS Records</company><price>9.90</price><year>1988</year></cd></catalog>
&#13;
答案 1 :(得分:0)
你应该改变这个:
<loop id="_loop1">
<xpath>count(/catalog/cd)</xpath>
<to id="_to1" uri="xslt:file:C:\Users\a638030\workspace\splitxml\data\order1.xsl"/>
<log id="_log2" message="${body}"/>
</loop>
进入这个:
<split id="_split1">
<xpath>/catalog/cd</xpath>
<to id="_to1" uri="xslt:file:C:\Users\a638030\workspace\splitxml\data\order1.xsl"/>
<log id="_log2" message="${body}"/>
</split>
执行此操作时,每个cd元素将进行一次交换,因此您必须相应地更改XSLT。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="CamelSplitIndex" />
<xsl:template match="/">
<xsl:result-document href="file$CamelSplitIndex.xml">
<document>
<xsl:value-of select="."/>
</document>
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>
我建议你看看Splitter EIP