使用C#解析格式错误的XML-SOAP

时间:2019-05-22 19:22:59

标签: c# xml parsing soap xml-parsing

我的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声明必须是文档中的第一个节点。

1 个答案:

答案 0 :(得分:2)

如果我对您的理解正确,那么您正在寻找的数据将在SOAP信封之后开始。查找的数据之后没有垃圾/不必要的内容。 SOAP标头不是以XML声明(<?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);
}