如何检测和修复XML文件中格式错误的CDATA部分?

时间:2017-07-13 20:36:11

标签: python regex python-2.7

带有CDATA的XML文件在第一次看到它不应该结束的<nav class="av-no-marg"> <ul class="pagination"> <li class="col-md-4"> <div> <a class="left carousel-control" href="#" data-slide="prev"> <span class="glyphicon glyphicon-chevron-left"></span> </a> </div> </li> <li class="col-md-4"> <div> TEST </div> </li> <li class="col-md-4"> <div> <a class="right carousel-control" href="#" data-slide="next"> <span class="glyphicon glyphicon-chevron-right"></span> </a> </div> </li> </ul> </nav> 时会意外中断。

我正在尝试将]]>替换为]]>。它应与]]]]><![CDATA[>匹配,但不能与]]>]]></Bold>匹配。

这是XML文件。

]]>]]></Bold>

1 个答案:

答案 0 :(得分:0)

你可以尝试至少通过获得整个灼伤来烧伤 错误的]]>个集合,然后将其转换为评论<!-- xxx -->

这样,您将停止它停止并能够获取剩余的记录。

我真的不想解释这个简单的正则表达式是不是真正的xml
解析准备好了(哈哈),但足以说明,这只是一个修复和 打捞作业。

一些注意事项 - 整个断言和第1组被用作
原子组(Python的re不支持)。

正则表达式 (?=(<!\[CDATA\[[\S\s]*?\]\]>))\1((?:(?:(?!<!\[CDATA\[[\S\s]*?\]\]>)[\S\s])*\]\]>)+)

格式化

 (?=
      ( <!\[CDATA\[ [\S\s]*? \]\]> )  # (1)
 )
 \1 
 (                             # (2 start)
      (?:
           (?:
                (?! <!\[CDATA\[ [\S\s]*? \]\]> )
                [\S\s] 
           )*
           \]\]>
      )+
 )                             # (2 end)

Python示例http://rextester.com/YACZ64236

import re

def callback(match):
    # Here you can further parse and/or do subs on 'group(2)'
    # the errant set of `]]>aa]]>]]>', etc.
    # For this we just cauterize it by enclosing in a comment block.
    return  match.group(1) + '<!-- ' + match.group(2) + '-->'

xml = ' <article><Date>2011-04-22T10:09:18Z</Date><Heading><![CDATA[data - content ]]></Heading><Body><![CDATA[contene - data  Normal data. ]]></Body></article> <article><Date>2011-02-26T12:48:09Z</Date><Heading><![CDATA[Content]]></Heading><Body><![CDATA[ Content-abc Help ]]>  {#  #} Content data - MORE  style="position: relative; left: -35%;" /> ]]>  More   0) { %> 0) { %> 0) { %> ]]>]]></Body></article><article><Date>2011-04-22T10:09:18Z</Date><Heading><![CDATA[data - content ]]></Heading><Body><![CDATA[contene - data  Normal data. ]]></Body></article>'
xml = '<root>' + xml + '</root>'

xmlnew = re.sub( r'(?=(<!\[CDATA\[[\S\s]*?\]\]>))\1((?:(?:(?!<!\[CDATA\[[\S\s]*?\]\]>)[\S\s])*\]\]>)+)', callback, xml )    

print( xmlnew )    

在浏览器中查看的输出

<?xml version="1.0"?>
-<root>
   -<article>
       <Date>2011-04-22T10:09:18Z</Date>
      -<Heading>
          <![CDATA[data - content ]]>
       </Heading>
      -<Body>
          <![CDATA[contene - data Normal data. ]]>
       </Body>
    </article>
   -<article>
       <Date>2011-02-26T12:48:09Z</Date>
      -<Heading>
          <![CDATA[Content]]>
       </Heading>
      -<Body>
          <![CDATA[ Content-abc Help ]]>
             <!-- {# #} Content data - MORE style="position: relative; left: -35%;" /> ]]> More 0) { %> 0) { %> 0) { %> ]]>]]>-->
       </Body>
    </article>
   -<article>
       <Date>2011-04-22T10:09:18Z</Date>
      -<Heading>
          <![CDATA[data - content ]]>
       </Heading>
      -<Body>
          <![CDATA[contene - data Normal data. ]]>
       </Body>
    </article>
</root>