我正在尝试从下面提到的XML(可能有效或无效)中提取cxml,其中包含多个cxml标记。我想要最顶级的cxml及其子cxml标记,但是得到的结果与预期不符。
正则表达式:
public static String selectCxmlFromXml(String xml) {
String cxml = "";
Pattern pattern = Pattern.compile(".*(<cXML.*</cXML>).*", Pattern.DOTALL);
Matcher matcher = pattern.matcher(xml);
if (matcher.matches()) {
cxml = matcher.group(1);
}
return cxml;
}
输入XML(这不是有效的XML):
<!DOCTYPE cXML SYSTEM "http://xml.cxml.org/schemas/cXML/1.2.037/cXML.dtd">1532298890669-3937185683464996079@216.109.111.68
<cXML payloadID="1532333614215-4720337288049634328@216.109.111.11" timestamp="2018-07-23T01:13:34-07:00">
<Response>
<Status code="200" text="OK"/>
<GetPendingResponse>
<cXML
payloadID="1532333614208-7005041222787302474@216.109.111.11" timestamp="2018-07-23T01:13:34-07:00">
<Message>
<DataAvailableMessage>
<InternalID domain="PendingMessages">140000000000000000010977255</InternalID>
</DataAvailableMessage>
</Message>
</cXML>
</GetPendingResponse>
</Response>
</cXML>
预期的响应:
<cXML payloadID="1532333614215-4720337288049634328@216.109.111.11" timestamp="2018-07-23T01:13:34-07:00">
<Response>
<Status code="200" text="OK"/>
<GetPendingResponse>
<cXML
payloadID="1532333614208-7005041222787302474@216.109.111.11" timestamp="2018-07-23T01:13:34-07:00">
<Message>
<DataAvailableMessage>
<InternalID domain="PendingMessages">140000000000000000010977255</InternalID>
</DataAvailableMessage>
</Message>
</cXML>
</GetPendingResponse>
</Response>
</cXML>
响应得到(不正确):
<cXML payloadID="1532333614208-7005041222787302474@216.109.111.11" timestamp="2018-07-23T01:13:34-07:00">
<Message>
<DataAvailableMessage>
<InternalID domain="PendingMessages">140000000000000000010977255</InternalID>
</DataAvailableMessage>
</Message>
</cXML>
</GetPendingResponse>
</Response>
</cXML>
请注意,第一个cxml声明及其数据已被跳过。
如果我使用.*(<cXML.*?</cXML>).*
,则仅选择内部cxml,而跳过外部cxml。
<cXML payloadID="1532333614208-7005041222787302474@216.109.111.11" timestamp="2018-07-23T01:13:34-07:00">
<Message>
<DataAvailableMessage>
<InternalID domain="PendingMessages">140000000000000000010977255</InternalID>
</DataAvailableMessage>
</Message>
</cXML>
我在这里做错了什么?
答案 0 :(得分:0)
经过一些摆弄,我遇到了这个正则表达式:
Traceback (most recent call last):
File "SDK_communicator.py", line 3, in <module>
sdkDll = WinDLL("C:\jhgsdk.dll")
File "c:\python36\lib\ctypes\__init__.py", line 348, in __init__
self._handle = _dlopen(self._name, mode)
OSError: [WinError 126] The specified module could not be found
from ctypes import *
sdkDll = WinDLL("C:\sdk.dll")
I also tried:
C:\\sdk.dll
C:\sdk.dll
C:/sdk.dll
解释其实际作用:
(<cXML>|<cXML.+>(?:\s|.)*<\/cXML>)
与开始标签匹配。可以包含或不包含属性。<cXML>|<cXML.+>
是一个 not-captureing-group ,它允许空白((?:\s|.)*
)和其他字母(\s
)的每种组合都匹配。 / li>
.
与结束标记匹配。答案 1 :(得分:0)
如果您原本已接受-遵循,遵守,遵守-标准,协议,RFC等,则没有人应该发送无效的XML。 请注意,可以在CDATA部分中发送非结构化数据。
但是,如果说有充分的理由要处理无效的XML,那么无效将是什么呢?以可预测的方式无效吗?让我们知道因为使用懒惰/贪婪的正则表达式可以(或者不可以)取决于内容的长度和正则表达式处理器。
如果您对顶级cXML感兴趣,请回答您的问题。我会简单地将字符串从从 String 开始的<cXML
的第一次出现到从字符串的末尾(向后)的</cXML>
的第一次出现的子字符串。您是否希望使用自闭合标签/>
?
答案 2 :(得分:0)
我发现我做错了。两件事:
1.使用find()代替match()
2.将正则表达式更改为(<cXML.*</cXML>)
,它将捕获整个cXML
新方法将是:
public static String selectCxmlFromXml(String xml) {
String cxml = "";
Pattern pattern = Pattern.compile("(<cXML.*</cXML>)", Pattern.DOTALL);
Matcher matcher = pattern.matcher(xml);
if (matcher.find()) {
cxml = matcher.group(1);
}
return cxml;
}
答案 3 :(得分:0)
这个问题已经有了很好的答案,但是我想分享这个网站:
http://www.regexplanet.com/advanced/java/index.html
在用Java编写正则表达式时确实很有帮助。 每当需要写一些奇怪的正则表达式时,我都会用它。
希望这会有所帮助。