在jboss fuse

时间:2017-12-20 13:51:34

标签: jboss routes apache-camel redhat jbossfuse

这是一个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;
&#13;
&#13;

我有这个XSLT:

&#13;
&#13;
<?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;
&#13;
&#13;

BLUEPRINT.xml(CAMEL ROUTE)

&#13;
&#13;
 <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;
&#13;
&#13;

当我运行此路线时,它表示错误如下:

&#13;
&#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;
&#13;
&#13; 在这一过程中记录了我提供输入的XML文件,然后它给循环路径中的XPATH表达带来了错误。

你可以帮我解决这个问题,还是有其他方法可以解决这个问题?

场景:我有这种情况,其中一个文件有1个带有多个子记录的XML。我需要拆分子记录并使用XSLT将其转换为多个XML(在JBOSS FUSE中)

2 个答案:

答案 0 :(得分:1)

谢谢你的帮助@ noMad17。

(BLUEPRINT.XML)使用ActiveMQ路由:

&#13;
&#13;
   <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;
&#13;
&#13;

XML INPUT:

&#13;
&#13;
<?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;
&#13;
&#13;

XSLT:

&#13;
&#13;
<?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;
&#13;
&#13;

输出MSG IN ACTIVEMQ:

&#13;
&#13;
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;
&#13;
&#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