dom4j读取xml内容时丢失换行符

(一)现象

很偶然的发现,很普通的SQL语句,在我们自己的Java程序中执行出错。
但是在数据库工具中执行正常,类似如下:

select '<YYYY>','<MM>','<DD>','<DDD>' -- test the datetime
,sysdate,systimestamp from dual

看日志,我们执行的语句变成了:

select '2022','09','14','257' -- test the datetime ,sysdate,systimestamp from dual 

由于多行变单行,所以注释掉了后续所有内容,导致报错:

业务处理错误: ORA-00923: FROM keyword not found where expected

(二)分析

这段SQL语句是保存在XML当中的,检查原始XML内容发现换行是存在的:
换行也是明显存在的。

......
<Task FileQ="XXX" SQL="select xxx,yyy,zzz -- test the datetime
,sysdate,systimestamp from dual" CHK="1" />
......

但是dom4j(org.w3c.dom也一样)读出来SAXReader.read()的时候呢,
数据内容中的换行就已经被替换成空格了。

研究了一阵,得到的结论是,Java并没有错……
因为XML格式,数据内容中的回车换行\r \n,应该使用转义字符&#0013; &#0010;
也就是说,上面那段XML,应该保存成如下格式:

......
<Task FileQ="XXX" SQL="select xxx,yyy,zzz -- test the datetime&#0013;&#0010;,sysdate,systimestamp from dual" CHK="1" />
......

(三)解决

只需要保存XML时使用转义字符就可以了。
Java程序在执行SQL时就可以读取到多行,第一行末的注释,也不会再影响后续行了。

正常情况下,这里就完结了。

⭕️

……

可是我们的Windows下的配置界面不是Web页面,也不是Java程序。
读写XML部分使用的是 🔗OmniXML

测试了一下,OmniXML读取转义/非转义的换行符都正常。
但是它保存换行符时,似乎只能非转义,也就是直接存,没有参数选项……

幸好有源代码。

检查源文件,找到转换转义字符的代码:

    case Ord(Value[iValue]) of
      34: Store('&quot;');
      38: Store('&amp;');
      39: Store('&apos;');
      60: Store('&lt;');
      62: Store('&gt;');
    else

添加回车换行的转义字符13 10,也就是\r \n(Pascal并不这样写)。

    case Ord(Value[iValue]) of
      10: Store('&#0010;');
      13: Store('&#0013;');
      34: Store('&quot;');
      38: Store('&amp;');
      39: Store('&apos;');
      60: Store('&lt;');
      62: Store('&gt;');
    else

(四)总结

这是 不同语言 / 不同时代 的程序模块,配合时出现的问题。

我们应该遵守规范:🔗 XML格式标准
但现实中我们无法完全控制输入的内容格式。

所以Java如果在XML读写上,给个选项(是否兼容原始未转义\r \n)才能完全解决。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值