gpt4 book ai didi

c# - 这个xml解析错误怎么处理?

转载 作者:行者123 更新时间:2023-11-30 17:11:32 26 4
gpt4 key购买 nike

考虑以下 C# 代码:

using System.Xml.Linq;

namespace TestXmlParse
{
class Program
{
static void Main(string[] args)
{
var testxml =
@"<base>
<elem1 number='1'>
<elem2>yyy</elem2>
<elem3>xxx <yyy zzz aaa</elem3>
</elem1>
</base>";
XDocument.Parse(testxml);
}
}
}

当然,我在解析时遇到 System.Xml.XmlException,提示 elem3。错误信息是这样的:

System.Xml.XmlException was unhandled
Message='aaa' is an unexpected token. The expected token is '='. Line 4, position 59.
Source=System.Xml
LineNumber=4
LinePosition=59

显然这不是真正的 Xml(我们从第三方获得 xml),虽然最好的答案是第三方在将其发送给我们之前清理他们的 xml,但有没有其他方法我可以在我将它交给解析器之前修复这个 xml?我设计了一个 hacky 方法来解决这个问题;捕获异常并使用它来告诉我需要在哪里查找应该转义的字符。我希望有一些更优雅和更全面的东西。

欢迎提出任何建议。

如果这是一个骗局,请指出其他问题;我会自己关闭这个。我对答案比任何因果报应更感兴趣。

编辑:

我想我的问题没有像我希望的那样清楚。我知道 elem3 中的“<”不正确;我试图找到一种优雅的方法来检测(并更正)在我尝试解析之前 任何格式错误的 xml。正如我所说,我从第三方获得此 xml,但我无法控制他们给我的内容。

最佳答案

我建议您不要操纵您收到的数据。如果它无效,那是您客户的问题。

编辑输入使其成为有效的 xml 可能会导致严重的问题,例如你可能最终会处理错误的数据而不是抛出错误(因为你尽力使 xml 有效,但这可能会导致不同的数据)。


[编辑]我仍然认为这不是一个好主意,但有时你必须做你必须做的事情。

这是一个非常简单的类,它解析输入并替换无效的开始标记。你可以用 regex (我不擅长)来做到这一点,这个解决方案并不完整,例如根据您的要求(或者说您得到的不好的 xml),您将不得不采用它(例如,扫描完整的 xml 元素,而不仅仅是“<”和“>”括号,将 CDATA 放在节点的内部文本周围,然后等等)。

我只是想说明你是如何做到的,所以如果它很慢/有错误请不要提示(正如我提到的,我不会这样做)。

class XmlCleaner
{

public void Clean(Stream sourceStream, Stream targetStream)
{
const char openingIndicator = '<';
const char closingIndicator = '>';
const int bufferSize = 1024;
long length = sourceStream.Length;
char[] buffer = new char[bufferSize];
bool startTagFound = false;
StringBuilder writeBuffer = new StringBuilder();

using(var reader = new StreamReader(sourceStream))
{
var writer = new StreamWriter(targetStream);

try
{
while (reader.Read(buffer, 0, bufferSize) > 0)
{
foreach (var c in buffer)
{
if (c == openingIndicator)
{
if (startTagFound)
{
// we have 2 following opening tags without a closing one
// just replace the first one
writeBuffer = writeBuffer.Replace("<", "&lt;");

// append the new one
writeBuffer.Append(c);
}
else
{
startTagFound = true;
writeBuffer.Append(c);
}
}
else if (c == closingIndicator)
{
startTagFound = false;
// write writebuffer...
writeBuffer.Append(c);
writer.Write(writeBuffer.ToString());
writeBuffer.Clear();
}
else
{
writeBuffer.Append(c);
}
}
}
}
finally
{
// unfortunately the streamwriter's dispose method closes the underlying stream, so e just flush it
writer.Flush();
}
}
}

测试它:

var testxml =
@"<base>
<elem1 number='1'>
<elem2>yyy</elem2>
<elem3>xxx <yyy zzz aaa</elem3>
</elem1>
</base>";

string result;

using (var source = new MemoryStream(Encoding.ASCII.GetBytes(testxml)))
using(var target = new MemoryStream()) {

XmlCleaner cleaner = new XmlCleaner();
cleaner.Clean(source, target);

target.Position = 0;
using (var reader = new StreamReader(target))
{
result = reader.ReadToEnd();
}
}

XDocument.Parse(result);

var expectedResult =
@"<base>
<elem1 number='1'>
<elem2>yyy</elem2>
<elem3>xxx &lt;yyy zzz aaa</elem3>
</elem1>
</base>";
Debug.Assert(result == expectedResult);

关于c# - 这个xml解析错误怎么处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11362863/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com