Разбор неправильно отформатированного XML-SOAP с C # - PullRequest
0 голосов
/ 22 мая 2019

У меня неверно сформированный файл 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 Ответ

2 голосов
/ 22 мая 2019

Если я вас правильно понимаю, то данные, которые вы ищете, начинаются после конверта 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. Или вы можете начать поиск объявления со 2-го символа, поэтому пропустите первый.

Это явно не надежное решение, которое будет работать в любом случае. Но, может быть, это будет работать во всех ваших случаях?

Пропуск строк

Если вы уверены, что сработает, чтобы всегда начинать чтение со строки 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);
}
...