【问题标题】:Find the parent Element in an invalid XML string at a given position在给定位置的无效 XML 字符串中查找父元素
【发布时间】:2013-02-06 23:00:27
【问题描述】:

例子:

...some string content here...
<test>
    <a>
        ...something...
    </a>
    <a/>
    {position 1}
    <b>{position 2}
        <c>
            ...something else...
            {position 3}
        </c>
        <c/>
        <d>
            <e/>
            {position 4}
            <e>
                ...another thing here...
                {position 5}
            </e>
        </d>
        {position 6}
    </b>
    {position 7}
...more xml and other sting content...

我需要在(例如)位置找到父封闭元素 上面指定的。

结果将是:{position 1} = test {position 2} = b {position 3} = c {位置 4} = d {位置 5} = e {位置 6} = b {位置 7} = 测试

备注: - 没有任何元素标签名称是已知的 - 漏洞字符串可能包含非 xml 内容 - 数据量很大(>50MB 文本文件)

必须实施一种搜索技术,从给定位置开始向后读取,直到找到有效匹配项(如果有)。

感谢

【问题讨论】:

  • 您使用什么语言?您是否可以选择将此字符串加载到 XML 对象中,然后执行查找父函数?这似乎是比正则表达式更顺畅的解决方案。
  • 我知道的每种语言都有很棒的 xml 解析器或包装 libxml 等。如果数据量很大,请使用 expat 之类的流式解析器。
  • 语言:C# 太大而无法加载,并且包含无效内容或不可接受的字符
  • 另外,有些元素可能没有匹配的结尾...
  • 为什么要解析无效的XML文件让我很困惑

标签: xml regex


【解决方案1】:

根据定义,无法解析无效的 XML。这就是为什么任何 XML 解析器都会拒绝解析它并返回错误。

如果 XML 解析器不能解析它,你也不能(基本上)。您所要求的不是一些可以被正则表达式抓取的简单字符串或简单的标签集合。为了在特定位置找到父标签,您确实必须进行完整解析(可能是无效数据!)。

更新:要了解我在说什么,请考虑在您的示例中找到 {position 1} 的父级。

  • 解决此问题的简单方法可能是“向后查找开始标签”。但是您显然不能使用找到的第一个开始标签 (&lt;a&gt;),因为它在位置之前关闭。
  • 因此,当您向后退时,您必须看到 &lt;/a&gt; 并记住 &lt;a&gt; 标记已关闭,这样您就不会将 &lt;a&gt; 视为父标记。
  • 当然,在您到达父级之前,可能有任意数量的打开和关闭标签。您必须跟踪所有这些(包括同一标签的多次出现)。

如您所见,这非常复杂。那是在您允许文件中存在任何无效元素之前。

一种可能可行的简单方法:如果您确切知道文件错误是什么,则可以删除这些错误,然后将更正后的文件输入 XML 解析器。

否则,您将不得不为特定品牌的无效 XML 编写自己的自定义解析器。根据文件中的错误类型,甚至可能都不可能。

【讨论】:

  • 这是第一个想法。删除错误并解析,但是,有些标签没有对应的结束标签,这会导致一些数据丢失。此外,还有自定义标签,例如... 我不知道命名空间名称。虽然我可以使用 xmlreader 设置来忽略命名空间,但我将不得不加载整个 xml。我目前只从给定位置向后读取,并尝试到达起始元素名称,我称之为位置的“根节点”。
  • @mtsiakiris,如果“某些标签没有对应的结束标签”我认为你的任务基本上是不可能的。
  • 不可能?不,没有什么是不可能的……重要的是你需要让它变得多么复杂。也许不太可能会更准确。 @mtsiakiris,我认为你一直在做你一直在做的事情。从您的已知点开始并向后阅读,直到您到达“父节点”。这不会很漂亮。
  • @cepatt,带有不匹配标签的文件可能包含歧义,因此对于“什么是父节点?”这个问题将没有正确答案。在那种情况下,任务显然是不可能的。
  • @cepatt,我只想要调用它当前位置的“根”元素的标签名称。我不在乎它是否包含在格式良好的 xml 中。可能是唯一的方法是向后搜索,同时保留所有有效的父元素标签名称,直到找到非关闭父元素。正如 dan1111 所说。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-25
  • 1970-01-01
  • 2012-12-24
相关资源
最近更新 更多