如何使用嵌套的XML文本解析XML

时间:2019-04-01 10:57:32

标签: c# .net xml

尝试使用具有自己的XML声明的嵌套XML对象读取XML文件。如预期的那样出现异常: Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it.

我如何才能将该特定元素读取为文本并将其解析为单独的XML文档以供以后反序列化?

<?xml version="1.0" encoding="UTF-8"?>
<Data>
  <Items>
    <Item>
      <Target type="System.String">Some target</Target>
      <Content type="System.String"><?xml version="1.0" encoding="utf-8"?><Data><Items><Item><surname type="System.String">Some Surname</surname><name type="System.String">Some Name</name></Item></Items></Data></Content>
    </Item>
  </Items>
</Data>

由于声明异常,我尝试的每种方法都会失败。

    var xml = System.IO.File.ReadAllText("Info.xml");

    var xDoc = XDocument.Parse(xml); // Exception

    var xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(xml); // Exception

    var xmlReader = XmlReader.Create(new StringReader(xml));
    xmlReader.ReadToFollowing("Content"); // Exception

我无法控制XML的创建。

2 个答案:

答案 0 :(得分:1)

我唯一知道的方法是摆脱非法的第二<?xml>声明。我编写了一个示例,该示例将简单地查找并丢弃第二个<?xml>。之后,该字符串已变为有效的XML,并且可以对其进行解析。您可能需要对其进行一些调整,以使其适合您的实际情况。

代码:

using System;
using System.Xml;

public class Program
{
    public static void Main()
    {
        var badXML = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<Data>
  <Items>
    <Item>
      <Target type=""System.String"">Some target</Target>
      <Content type=""System.String""><?xml version=""1.0"" encoding=""utf-8""?><Data><Items><Item><surname type=""System.String"">Some Surname</surname><name type=""System.String"">Some Name</name></Item></Items></Data></Content>
    </Item>
  </Items>
</Data>";

        var goodXML = badXML.Replace(@"<Content type=""System.String""><?xml version=""1.0"" encoding=""utf-8""?>"
                                   , @"<Content type=""System.String"">");

        var xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(goodXML);

        XmlNodeList itemRefList = xmlDoc.GetElementsByTagName("Content");
        foreach (XmlNode xn in itemRefList)
        {
            Console.WriteLine(xn.InnerXml);
        }
    }
}

输出:

<Data><Items><Item><surname type="System.String">Some Surname</surname><name type="System.String">Some Name</name></Item></Items></Data>

正在运行的DotNetFiddle:https://dotnetfiddle.net/ShmZCy

也许无需多说:如果创建无效XML的东西已经应用通用规则将嵌套的XML包装在<![CDATA[ .... ]]>块中,则不需要所有这些。

答案 1 :(得分:1)

<?xml ...?>处理声明仅在XML文档的第一行有效,因此给您的XML格式不正确。这将使得在不更改源文档(并且您已经表明不可能)或预处理源文件的情况下按原样进行解析非常困难。

您可以尝试:

  1. 使用正则表达式或字符串操作去除<?xml ?>指令,但治愈可能比疾病还差。
  2. HTMLAgilityPack,它实现了更宽容的解析器may work with an XML document

除此之外,文档的生产者还应考虑生成格式正确的XML:

  1. CDATA部分可以帮助您解决问题,但请注意,CDATA不能包含]]>结束标记。
  2. 将XML文本转义为XML可以正常工作;也就是说,使用标准例程将<转换为&lt;,依此类推。
  3. XML名称空间在这里也可以提供帮助,但是一开始它们可能令人生畏。