在尝试处理xml之前,我需要从输入xml中删除文档类型和实体声明。
我正在使用以下代码删除文档类型和实体:
fileContent = fileContent.replaceAll("<!ENTITY ((.|\n|\r)*?)\">", "");
fileContent = fileContent.replaceAll("<!DOCTYPE((.|\n|\r)*?)>", "");
这将删除实体,然后删除文档类型。 如果xml在xml中包含以下doctype声明,则效果很好:
<!DOCTYPE ichicsr SYSTEM "http://www.w3.org/TR/html4/frameset.dtd">
<!DOCTYPE ichicsr SYSTEM "D:\UPGRADE\NTServices\Server\\Xml21.dtd"
[<!ENTITY % entitydoc SYSTEM "D:\UPGRADE\NTServices\Server\\latin-entities.dtd"> %entitydoc;]>
但是,如果我具有以下给出的doctype,它将无法正常工作,并且xml中的根标记将被剥离:
<!DOCTYPE ichicsr SYSTEM "D:\UPGRADE\NTServices\Server\\Xml21.dtd"
[<!ENTITY % entitydoc SYSTEM 'D:\UPGRADE\NTServices\Server\\Xml21.dtd'>
]>
请让我知道我使用的正则表达式是否错误或需要采取任何其他措施。
答案 0 :(得分:3)
您的方法行不通,因为在"
正则表达式中,最终>
之前需要ENTITIY
。您可以在那里将\"
替换为['\"]
。
此外,切勿在任何正则表达式中使用(.|\n|\r)*?
,因为它是性能杀手。而是将.*?
与Pattern.DOTALL
(或内联(?s)
变体)一起使用,或至少与[\s\S]*?
一起使用。
但是,有更好的方法:将两个正则表达式合并为一个:
fileContent = fileContent.replaceAll("(?i)<!DOCTYPE[^<>]*(?:<!ENTITY[^<>]*>[^<>]*)?>", "");
请参见regex demo。
详细信息
(?i)
-不区分大小写的Pattern.CASE_INSENSITIVE
内联修饰符<!DOCTYPE
-文字[^<>]*
-除<
和>
以外的0多个字符(?:<!ENTITY[^<>]*>[^<>]*)?
-的可选出现
<!ENTITY
[^<>]*
-除<
和>
以外的0多个字符>
-一个>
字符[^<>]*
-除<
和>
以外的0多个字符>
-一个>
字符。