来自 WebService 的未净化 XML,如何净化
Unsanitized XML from WebService, How to sanitize
我收到来自 WebService 的 "XML" 响应,该响应未经过清理。意思是它包含非法字符、特殊字符、html标签和十六进制.
净化此响应的最佳方法是什么?
这是服务中的一个 Xml 示例。
<root>
<response>
<type>E</type>
<code>CMNE_00034</code>
<source>CMNQ3030</source>
<message>some valid message here.</message>
<detail>Error details here
line 114: endif
line 115: edit
line 116: else
> line 117: call LP_ACCEPT()
line 118: return ($status)
line 119: endif
line 120: done<end of module> // invalid here
at CMNQ3030.EXEC line 117: call LP_ACCEPT()
at GPCSY_RUN line 5: activate INSTANCENAME."EXEC"( )
at CSYV1000.LOGON line 159: call GPCSY_RUN()
</detail>
</response>
</root>
我已经尝试了很多东西,从创建一个有设置的 XmlReader
,就像这样。
public XDocument CreateXmlDocument(string content)
{
using (var reader = XmlReader.Create(new StringReader(content), CreateXmlReaderSettings()))
{
return XDocument.Load(reader);
}
}
private static XmlReaderSettings CreateXmlReaderSettings()
{
return new XmlReaderSettings { CheckCharacters = false };
}
从 XmlDocument 更改为 XDocument 并在实际阅读之前使用 Encoding.UTF8.GetBytes
。
.NET 中的 XMLReader
、XDocument
等基础设施不太可能接受阅读和解析格式错误的请求 XML。
我建议在将 XML 加载到 XML 对象之前对其进行预处理。
在上面的例子中,Web 服务似乎在 <detail>...</detail>
元素中返回一条错误消息,该元素实际上应该像这样包装在 CDATA 中:
<root>
<response>
<type>E</type>
<code>CMNE_00034</code>
<source>CMNQ3030</source>
<message>some valid message here.</message>
<detail><![CDATA[
Error details here
line 114: endif
line 115: edit
line 116: else
> line 117: call LP_ACCEPT()
line 118: return ($status)
line 119: endif
line 120: done<end of module> // invalid here
at CMNQ3030.EXEC line 117: call LP_ACCEPT()
at GPCSY_RUN line 5: activate INSTANCENAME."EXEC"( )
at CSYV1000.LOGON line 159: call GPCSY_RUN()
]]>
</detail>
</response>
</root>
您应该能够非常快速地组合一个解析器来查找、提取和包装 <detail>
标记末尾和 </detail>
标记开始之间的文本 <[CDATA[
和 ]]>
标签。
当然,您的服务 XML 中可能还有其他字段也包含字符串数据或格式错误的字符等,您可能需要查找这些字符并将其替换为例如常规字符表达式等
更正后,将干净的 XML 加载到 XMLDocuments/XDocuments 等应该没有困难
HTH.
我收到来自 WebService 的 "XML" 响应,该响应未经过清理。意思是它包含非法字符、特殊字符、html标签和十六进制.
净化此响应的最佳方法是什么?
这是服务中的一个 Xml 示例。
<root>
<response>
<type>E</type>
<code>CMNE_00034</code>
<source>CMNQ3030</source>
<message>some valid message here.</message>
<detail>Error details here
line 114: endif
line 115: edit
line 116: else
> line 117: call LP_ACCEPT()
line 118: return ($status)
line 119: endif
line 120: done<end of module> // invalid here
at CMNQ3030.EXEC line 117: call LP_ACCEPT()
at GPCSY_RUN line 5: activate INSTANCENAME."EXEC"( )
at CSYV1000.LOGON line 159: call GPCSY_RUN()
</detail>
</response>
</root>
我已经尝试了很多东西,从创建一个有设置的 XmlReader
,就像这样。
public XDocument CreateXmlDocument(string content)
{
using (var reader = XmlReader.Create(new StringReader(content), CreateXmlReaderSettings()))
{
return XDocument.Load(reader);
}
}
private static XmlReaderSettings CreateXmlReaderSettings()
{
return new XmlReaderSettings { CheckCharacters = false };
}
从 XmlDocument 更改为 XDocument 并在实际阅读之前使用 Encoding.UTF8.GetBytes
。
.NET 中的 XMLReader
、XDocument
等基础设施不太可能接受阅读和解析格式错误的请求 XML。
我建议在将 XML 加载到 XML 对象之前对其进行预处理。
在上面的例子中,Web 服务似乎在 <detail>...</detail>
元素中返回一条错误消息,该元素实际上应该像这样包装在 CDATA 中:
<root>
<response>
<type>E</type>
<code>CMNE_00034</code>
<source>CMNQ3030</source>
<message>some valid message here.</message>
<detail><![CDATA[
Error details here
line 114: endif
line 115: edit
line 116: else
> line 117: call LP_ACCEPT()
line 118: return ($status)
line 119: endif
line 120: done<end of module> // invalid here
at CMNQ3030.EXEC line 117: call LP_ACCEPT()
at GPCSY_RUN line 5: activate INSTANCENAME."EXEC"( )
at CSYV1000.LOGON line 159: call GPCSY_RUN()
]]>
</detail>
</response>
</root>
您应该能够非常快速地组合一个解析器来查找、提取和包装 <detail>
标记末尾和 </detail>
标记开始之间的文本 <[CDATA[
和 ]]>
标签。
当然,您的服务 XML 中可能还有其他字段也包含字符串数据或格式错误的字符等,您可能需要查找这些字符并将其替换为例如常规字符表达式等
更正后,将干净的 XML 加载到 XMLDocuments/XDocuments 等应该没有困难
HTH.