13

我从第 3 方获得了一个 XML 文件,我必须在我的应用程序中导入该文件,并且 XML 在内部文本中有未转义 & 的元素,他们不会解决这个问题!所以我的问题是处理这个问题的最佳方法是什么?

这个 XML 非常大,而且修复速度必须很快,我的第一个解决方案是用 & 符号替换 & 字符,但出于明显的原因,我真的不喜欢这个“解决方案”。我不知道如何将 XmlStringReader 与此类 XML 一起使用,因为在此类行上会引发异常,因此我不能在内部文本上使用 HtmlEncode。我试图将 XmlTextReader 设置Settings.CheckCharacters为 false 但没有结果。

这是示例, & 在元素中,并且在该字段中可以是任何可以在某些公司名称中的内容,因此我的替换修复可能不适用于其他公司名称,我想以某种方式使用 HtmlEncode,但仅限当然是关于内部文本。

<komitent ID="001398">
  <sifra>001398</sifra>
  <redni_broj>001398</redni_broj>
  <naziv>LJUBICA & ŽARKO</naziv>
  <adresa1>Odvrtnica 27</adresa1>
  <adresa2></adresa2>
  <drzava>HRVATSKA</drzava>
  <grad>Zagreb</grad>
</komitent>
4

6 回答 6

4

下面的关键信息是,除非您知道输入文件的确切格式,并保证与 XML 的任何偏差都是一致的,否则您无法以编程方式修复而不冒修复不正确的风险。

当且仅在以下情况下,通过替换来修复它&是一个可接受的解决方案:&amp;

  1. 这些数据没有可接受的格式良好的来源。

    • 正如@Darin Dimitrov 评论的那样,尝试找到一个更好的提供者,或者让这个提供者修复它。
    • JSON(例如)比格式不正确的 XML 更可取,即使您不使用 javascript。
  2. 这是一次性(或至少非常罕见)的导入。

    • 如果您必须在运行时获取它,那么此解决方案将不起作用。
  3. 您可以不断迭代,为其设计新的修复程序,为遇到的每个问题添加解决方案。

    • 您可能会发现,一旦通过转义&字符“修复”了它,就会出现其他错误。
  4. 您有资源手动检查“固定”数据的完整性。

    • 您“修复”的错误可能比您意识到的更微妙。
  5. 文档中没有格式正确的实体 -

    • 简单地替换&&amp;将错误地更改&quot;&amp;quot;. 您可能能够解决这个问题,但不要天真地认为它可能有多么棘手(实体可能在 DTD 中定义,可能引用 unicode 代码点......)

    • 如果它是一个行为不端的特定元素,您可以考虑用 包装元素的内容 <![CDATA ]]>,但这仍然依赖于您能够可靠地找到开始和结束标签。

于 2011-05-16T15:53:14.567 回答
2

从改变你的心态开始。输入不是 XML,所以不要称它为 XML。甚至不要使用“xml”来标记您的问题。它不是 XML 的事实意味着您不能对它使用任何 XML 工具,也无法获得 XML 数据交换的任何好处。您正在处理一种没有规范且没有任何工具的专有格式。像对待任何其他专有格式一样对待它——尝试发现你所得到的规范,并为它编写一个解析器。

于 2011-05-16T21:47:15.687 回答
2

如果您知道文件的标签并希望“确定”标签内可能包含可疑数据的文本,您可以执行以下操作:

private static string FixBadXmlText(string xmlText)
{           
    var unreliableTextTags = new[] { "message", "otherdata", "stacktrace", "innerexception" };

    foreach(var tag in unreliableTextTags)
    {
        string openTag = "<" + tag + ">";
        string closeTag = "</" + tag + ">";
        xmlText = xmlText.Replace(openTag, openTag + "<![CDATA[").Replace(closeTag, "]]>" + closeTag);
    }

    return xmlText;
}

XML 解析器不会解释CDATA 节( ) 中的任何内容,<![CDATA[ {your text here} ]]>因此不需要转义。当我想要解析一些没有正确转义输入的糟糕的 XML 时,这对我很有帮助。

于 2014-01-14T14:46:30.673 回答
0

由于您的起始 XML 是错误的,因此您不能使用任何 XmlReaders,因为它们无法正确读取它。

如果只有 XML 节点的值不是 htmlEncoded,那么您必须手动读取行、解析(获取 xml 节点名称及其值)、编码并输出到新文件。

很多时候我们最终会遇到类似的情况,所以我理解你的痛苦——虽然大多数时候,错误有一些“规则”,所以我猜这里他们没有编码商业名称(也许是街道名称) , 所以你可以只搜索那个 string <naziv>,它是结束标记</naziv>和 HtmlEncode 之间的所有内容。还有,因为是企业名,所以不会有换行,可以让你的生活轻松不少……

于 2011-05-16T15:04:29.173 回答
0

您可以根据结构的复杂程度尝试使用正则表达式:

Regex mainSplitter = new Regex("<komitent ID=\"([0-9]*)\">(.*?)</komitent>");
Regex nazivFinder = new Regex("<naziv>(.*?)</naziv>");

foreach (Match item in mainSplitter.Matches(test))
{
    Console.WriteLine(item);

    string naziv = null;

    Match node = nazivFinder.Match(item.Groups[2].Value);
    if (node != null)
        naziv = node.Groups[1].Value;
}
于 2011-05-16T18:30:12.913 回答
0

您可以将文件作为 XPL 处理,甚至可以使用 XPL 解析器将此类文件转换为有效的 XML。XPL(可扩展过程语言)与 XML 类似,但解析器允许在文本字段中使用 XML 的“特殊字符”。因此,您实际上可以通过 XPL 进程运行无效的 XML 文件(由于特殊字符而无效)。在某些情况下,您可以使用 XPL 处理器而不是 XML 处理器。您还可以使用它来预处理无效文件,而不会造成任何性能损失。人工智能、XML 和 Java 并发

于 2015-04-26T15:18:46.437 回答