88

我正在尝试在 WiX 安装程序中解析一些 XML。XML 将是我从 Web 服务器返回的所有错误的对象。我在使用此代码的问题标题中收到错误:

XmlDocument xml = new XmlDocument();
try
{
    xml.LoadXml(myString);
}
catch (Exception ex)
{
    System.IO.File.WriteAllText(@"C:\text.txt", myString + "\r\n\r\n" + ex.Message);
    throw ex;
}

myString这是(如 的输出所示text.txt

<?xml version="1.0" encoding="utf-8"?>
<Errors></Errors>

text.txt出来看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<Errors></Errors>

Data at the root level is invalid. Line 1, position 1.

我需要解析这个 XML,以便查看是否有任何错误。

4

11 回答 11

146

隐藏的字符可能是 BOM。可以在此处找到问题的解释和解决方案,这归功于 James Schubert,基于此处找到的 James Brankin 的回答。

虽然前面的答案确实删除了隐藏字符,但它也删除了整个第一行。更精确的版本是:

string _byteOrderMarkUtf8 = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
if (xml.StartsWith(_byteOrderMarkUtf8))
{
    xml = xml.Remove(0, _byteOrderMarkUtf8.Length);
}

从 Azure blob 获取 XSLT 文件并将其加载到 XslCompiledTransform 对象时,我遇到了这个问题。在我的机器上,该文件看起来很好,但是在将其作为 blob 上传并取回后,添加了 BOM 字符。

于 2015-01-02T14:13:22.637 回答
72

改用Load()方法,就能解决问题。看更多

于 2014-03-14T01:49:20.660 回答
16

这里的问题是myString有那个标题行。第一行的开头有一些隐藏字符,或者该行本身导致了错误。我像这样切掉了第一行:

xml.LoadXml(myString.Substring(myString.IndexOf(Environment.NewLine)));

这解决了我的问题。

于 2013-07-22T19:31:34.107 回答
10

我认为问题在于编码。这就是为什么删除第一行(带有编码字节)可能会解决问题的原因。

对根级别数据的解决方案无效。第 1 行,位置 1. inXDocument.Parse(xmlString)将其替换为XDocument.Load( new MemoryStream( xmlContentInBytes ) );

我注意到我的 xml 字符串看起来不错:

<?xml version="1.0" encoding="utf-8"?>

但在不同的文本编辑器编码中,它看起来像这样:

?<?xml version="1.0" encoding="utf-8"?>

最后我不需要 xml 字符串,而是 xml byte[]。如果您需要使用字符串,您应该在字符串中查找“不可见”字节并使用编码来调整 xml 内容以进行解析或加载。

希望它会有所帮助

于 2015-09-22T09:25:30.110 回答
3

使用不同的编码保存文件:

文件 > 将文件另存为... > 另存为不带签名的 UTF-8。

在 VS 2017 中,您可以在“保存”按钮旁边找到编码作为下拉菜单。

于 2017-09-13T15:31:27.870 回答
3

我通过直接编辑字节数组解决了这个问题。收集 UTF8 前导码并直接删除标头。之后,您可以使用 GetString 方法将 byte[] 转换为字符串,见下文。作为预防措施,我也删除了 \r 和 \t 。

XmlDocument configurationXML = new XmlDocument();
List<byte> byteArray = new List<byte>(webRequest.downloadHandler.data);

foreach(byte singleByte in Encoding.UTF8.GetPreamble())
{
     byteArray.RemoveAt(byteArray.IndexOf(singleByte));
}
string xml = System.Text.Encoding.UTF8.GetString(byteArray.ToArray());
       xml = xml.Replace("\\r", "");
       xml = xml.Replace("\\t", "");
于 2018-08-17T09:28:26.060 回答
2

如果您的 xml 在字符串中,请使用以下内容删除任何字节顺序标记:

        xml = new Regex("\\<\\?xml.*\\?>").Replace(xml, "");
于 2018-04-29T13:45:33.777 回答
2

起初我在转义“&”字符时遇到了问题,然后变音符号和特殊字母显示为问号,最后出现了 OP 提到的问题。

我查看了答案,并使用@Ringo 的建议尝试 Load() 方法作为替代方法。这让我意识到我可以用其他方式来处理我的回复,而不仅仅是一个字符串。

使用 System.IO.Stream 而不是 string 为我解决了所有问题。

var response = await this.httpClient.GetAsync(url);
var responseStream = await response.Content.ReadAsStreamAsync();
var xmlDocument = new XmlDocument();
xmlDocument.Load(responseStream);

Load() 很酷的地方在于,该方法会自动检测输入 XML 的字符串格式(例如,UTF-8、ANSI 等)。看更多

于 2020-09-14T15:38:16.207 回答
1

Stream此错误的主要罪魁祸首是在将数组或byte[]数组转换为 .NET时确定编码的逻辑string

使用StreamReadercreated 并将第二个构造函数参数detectEncodingFromByteOrderMarks设置为 true,将确定正确的编码并创建string不会破坏XmlDocument.LoadXml方法。

public string GetXmlString(string url)
{
    using var stream = GetResponseStream(url);
    using var reader = new StreamReader(stream, true);
    return reader.ReadToEnd(); // no exception on `LoadXml`
}

常见的错误是在or上盲目地使用UTF8编码。当在 Visual Studio 调试器中检查或复制粘贴到某处时,下面的代码会产生看起来有效的代码,但是当与没有 BOM 的 UTF8 一起使用或文件的编码方式不同时,它将产生异常。streambyte[]stringLoadLoadXml

public string GetXmlString(string url)
{
    byte[] bytes = GetResponseByteArray(url);
    return System.Text.Encoding.UTF8.GetString(bytes); // potentially exception on `LoadXml`
}
于 2020-10-19T15:15:32.710 回答
0

我找到了解决方案之一。对于您的代码,这可能如下所示 -

XmlDocument xml = new XmlDocument();
try
{
    // assuming the location of the file is in the current directory 
    // assuming the file name be loadData.xml
    string myString = "./loadData.xml";
    xml.Load(myString);
}
catch (Exception ex)
{
    System.IO.File.WriteAllText(@"C:\text.txt", myString + "\r\n\r\n" + ex.Message);
    throw ex;
}
于 2018-08-13T21:12:53.193 回答
0

如果我们使用 XDocument.Parse(@"")。使用@它可以解决问题。

于 2020-02-07T08:26:26.113 回答