【问题标题】:Parsing wrongly formatted XML-SOAP with C#使用 C# 解析格式错误的 XML-SOAP
【发布时间】:2019-05-22 19:22:58
【问题描述】:

我有需要解析的格式错误的 XML (SOAP) 文件。问题是 XML 没有正确的标头标签。

我尝试使用 XDocument 和 XmlDocument 解析文件,但都没有成功。 XML 从第 30 行开始,所以也许有一些方法可以在 XML 解析器读取文件之前跳过这些行?

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:eb="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd">
<SOAP-ENV:Header>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="Finvoice.xsl"?>
<GGVersion="2.01" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="a.xsd">

XmlReaderSettings settings = new XmlReaderSettings();
                  settings.ConformanceLevel = ConformanceLevel.Fragment;
                  XmlReader r = XmlReader.Create(file.FullName, settings);
                  XmlDocument xDoc = new XmlDocument();
                  xDoc.PreserveWhitespace = true;
                  xDoc.LoadXml("<xml/>");
                  xDoc.DocumentElement.CreateNavigator().AppendChild(r);

                XmlNamespaceManager manager = new XmlNamespaceManager(xDoc.NameTable);

一旦尝试解析,我得到:意外的 xml 声明。 xml声明必须是文档中的第一个节点......

【问题讨论】:

  • 这是 SOAP 消息数据中的新 XML 声明吗?除非您从消息中删除了 CDATA 标记,否则我认为没有任何方法可以让任何 XML 解析器接受它。
  • 不,文件中没有任何 CDATA -tag。我稍微编辑了第一条消息,以便更好地了解 SOAP 标头。
  • 有... options...
  • @sukkis 我不太明白 XML 看起来如何。您的意思是先有一个 SOAP 标头,然后然后是一个完整的 XML 文档,而您想丢弃该 soap 标头吗?在您要查找的 XML 之后没有 SOAP 信封吗?在这种情况下,这似乎可以通过简单的Substring 方法调用来解决。
  • @sukkis 我添加了另一种跳到第 30 行的方法。

标签: c# xml parsing soap xml-parsing


【解决方案1】:

如果我对您的理解正确,那么您要查找的数据在 SOAP 信封之后开始。在您查找的数据之后没有垃圾/不重要的内容。 SOAP 标头以 XML 声明开头(&lt;?xml version= 等)。

寻找文档的开头

一个简单的解决方案是找到 XML 文档的开头(您要查找的数据),然后删除之前的所有内容。

var startOfRealDocumentMarker = "<?xml version=\"1.0\"";
var startIndex = dirtyXmlString.IndexOf(startOfRealDocumentMarker);
if(startIndex == -1) {
    throw new Exception("Start of XML not found. Now what?");
}
var cleanXmlString = dirtyXmlString.Substring(startIndex);

如果 SOAP 标头也有 XML 声明,则可以改为查找 SOAP 信封的结束标记。或者你可以从第二个字符开始寻找声明,这样你就可以跳过第一个。

这显然不是一个适用于所有情况的万无一失的解决方案。但也许它适用于所有您的案例?

跳线

如果您确定始终从输入文件的第 30 行开始读取会起作用,则可以改用此方法。

XmlDocument xDoc = new XmlDocument();    
using (var rdr = new StreamReader(pathToXmlFile))
{
    // Skip until reader is positioned at start of line 30
    for (var i = 0; i < 29; ++i)
    {
        rdr.ReadLine();
    }       
    // Load document from current position of reader
    xDoc.Load(rdr);
}

【讨论】:

    猜你喜欢
    • 2012-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-03
    • 1970-01-01
    • 1970-01-01
    • 2011-01-14
    • 1970-01-01
    相关资源
    最近更新 更多