WSO2 MI 4.2.0读取含CTRL-CHAR(26)的XML报异常求助
WSO2 MI 4.2.0读取含控制字符(Code 26)的XML文件报错求助
在WSO2 MI 4.2.0中读取包含控制字符(CTRL-CHAR,代码26)的XML文件时,抛出如下异常:com.ctc.wstx.exc.WstxUnexpectedCharException: Illegal character ((CTRL-CHAR, code 26))
示例XML文件的<value>标签中包含显示为空格的Char26字符,读取时触发上述异常。已按照WSO2 MI官方文档添加XMLOutputFactory.properties文件,但问题仍未解决,寻求解决方法。
代理配置
<?xml version="1.0" encoding="UTF-8"?> <proxy name="readXMLwithWhiteCharacters" startOnLoad="true" transports="http https" xmlns="http://ws.apache.org/ns/synapse"> <target> <inSequence> <fileconnector.read> <source>file:///opt/data/sample.xml</source> <contentType>application/xml</contentType> <filePattern>.*/.xml</filePattern> </fileconnector.read> <property expression="json-eval($)" name="file-content" scope="default" type="STRING"/> <log level="full"> <property expression="get-property('file-content')" name="log-json-response"/> </log> </inSequence> <outSequence/> <faultSequence/> </target> </proxy>
示例XML片段:
<readone> <value> </value> </readone>
(注:<value>标签内的空格实际为Code 26控制字符)
错误日志
[2023-07-07 02:51:50,296] ERROR {org.wso2.carbon.connector.util.ResultPayloadCreate} - Error while processing the file/folder org.apache.axiom.om.OMException: com.ctc.wstx.exc.WstxUnexpectedCharException: Illegal character ((CTRL-CHAR, code 26)) at [row,col {unknown-source}]: [2,9] at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:296) at org.apache.axiom.om.impl.llom.OMElementImpl.buildNext(OMElementImpl.java:653) at org.apache.axiom.om.impl.llom.OMElementImpl.getFirstOMChild(OMElementImpl.java:670) at org.apache.axiom.om.impl.llom.OMElementImpl.getChildren(OMElementImpl.java:352) at org.apache.axiom.om.impl.util.OMSerializerUtil.serializeChildren(OMSerializerUtil.java:554) at org.apache.axiom.om.impl.llom.OMElementImpl.internalSerialize(OMElementImpl.java:879) at org.apache.axiom.om.impl.util.OMSerializerUtil.serializeChildren(OMSerializerUtil.java:556) at org.apache.axiom.om.impl.llom.OMElementImpl.internalSerialize(OMElementImpl.java:879) at org.apache.axiom.om.impl.util.OMSerializerUtil.serializeChildren(OMSerializerUtil.java:556) at org.apache.axiom.om.impl.llom.OMElementImpl.internalSerialize(OMElementImpl.java:879) at org.apache.axiom.soap.impl.llom.SOAPEnvelopeImpl.internalSerialize(SOAPEnvelopeImpl.java:230) at org.apache.axiom.om.impl.llom.OMSerializableImpl.serialize(OMSerializableImpl.java:125) at org.apache.axiom.om.impl.llom.OMSerializableImpl.serialize(OMSerializableImpl.java:113) at org.apache.axiom.om.impl.llom.OMElementImpl.toString(OMElementImpl.java:992) at org.wso2.carbon.connector.util.ResultPayloadCreate.buildFile(ResultPayloadCreate.java:183) at org.wso2.carbon.connector.FileRead.connect(FileRead.java:102) at org.wso2.carbon.connector.core.AbstractConnector.mediate(AbstractConnector.java:32) at org.apache.synapse.mediators.ext.ClassMediator.updateInstancePropertiesAndMediate(ClassMediator.java:178) at org.apache.synapse.mediators.ext.ClassMediator.mediate(ClassMediator.java:97) at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:110) at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:72) at org.apache.synapse.mediators.template.TemplateMediator.mediate(TemplateMediator.java:136) at org.apache.synapse.mediators.template.InvokeMediator.mediate(InvokeMediator.java:170) at org.apache.synapse.mediators.template.InvokeMediator.mediate(InvokeMediator.java:93) at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:110) at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:72) at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:158) at org.apache.synapse.core.axis2.ProxyServiceMessageReceiver.receive(ProxyServiceMessageReceiver.java:240) at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180) at org.apache.synapse.startup.tasks.MessageInjector.execute(MessageInjector.java:336) at org.wso2.micro.integrator.mediation.ntask.NTaskAdapter.execute(NTaskAdapter.java:105) at org.wso2.micro.integrator.ntask.core.impl.TaskQuartzJobAdapter.execute(TaskQuartzJobAdapter.java:63) at org.quartz.core.JobRunShell.run(JobRunShell.java:202) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:829) Caused by: com.ctc.wstx.exc.WstxUnexpectedCharException: Illegal character ((CTRL-CHAR, code 26)) at [row,col {unknown-source}]: [2,9] at com.ctc.wstx.sr.StreamScanner.throwInvalidSpace(StreamScanner.java:666) at com.ctc.wstx.sr.BasicStreamReader.readTextPrimary(BasicStreamReader.java:4576) at com.ctc.wstx.sr.BasicStreamReader.nextFromTree(BasicStreamReader.java:2879) at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1072) at org.apache.axiom.util.stax.wrapper.XMLStreamReaderWrapper.next(XMLStreamReaderWrapper.java:225) at org.apache.axiom.util.stax.dialect.DisallowDoctypeDeclStreamReaderWrapper.next(DisallowDoctypeDeclStreamReaderWrapper.java:34) at org.apache.axiom.om.impl.builder.StAXOMBuilder.parserNext(StAXOMBuilder.java:681) at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:214) ... 37 more
解决方法
1. 配置Woodstox解析器允许控制字符
WSO2 MI使用Woodstox作为XML解析器,默认会拒绝XML中的控制字符。需要添加XMLInputFactory的配置(而非仅XMLOutputFactory):
- 在MI的
conf目录下创建XMLInputFactory.properties文件,添加内容:
javax.xml.stream.isSupportingExternalEntities=false com.ctc.wstx.acceptAllXmlCharacters=true
- 或者在MI启动脚本中添加JVM参数:
-Dcom.ctc.wstx.acceptAllXmlCharacters=true
修改后重启MI服务。
2. 修改文件读取逻辑,先过滤控制字符
若无法修改解析器配置,可先将文件读取为纯文本,过滤控制字符后再转为XML:
<proxy name="readXMLwithWhiteCharacters" startOnLoad="true" transports="http https" xmlns="http://ws.apache.org/ns/synapse"> <target> <inSequence> <fileconnector.read> <source>file:///opt/data/sample.xml</source> <contentType>text/plain</contentType> <filePattern>.*/.xml</filePattern> </fileconnector.read> <property expression="json-eval($)" name="file-content" scope="default" type="STRING"/> <!-- JavaScript脚本过滤ASCII控制字符(保留换行、回车、制表符) --> <script language="js"><![CDATA[ var rawContent = mc.getProperty('file-content'); var cleanedContent = rawContent.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, ''); mc.setProperty('cleaned-file-content', cleanedContent); ]]></script> <!-- 将清理后的内容转为XML payload --> <payloadFactory media-type="xml"> <format>$1</format> <args> <arg evaluator="xml" expression="get-property('cleaned-file-content')"/> </args> </payloadFactory> <log level="full"> <property expression="get-property('cleaned-file-content')" name="cleaned-content"/> </log> </inSequence> <outSequence/> <faultSequence/> </target> </proxy>
3. 预处理源XML文件
从XML规范来讲,Code 26属于非法控制字符。若有条件,建议提前清理源XML文件中的此类字符,从根源避免解析错误。
内容的提问来源于stack exchange,提问作者aditi21
相关产品推荐
相关产品推荐

