Python lxml库在空标记中包含None

时间:2017-10-20 16:41:40

标签: python python-3.x lxml

正如mzjn所建议的那样,我正在改变整个问题并尝试简化它。

我有这个XML:

<Content Version="1.0" Name="Cont">
 <Element Ref="Text_4158" ElementType="ItISSomething" GroupName="Some_Content">
  <body>
    <p>Some content is here.</p>
  </body>
 </Element>
 <Element Ref="List_585" ElementType="ListElements" GroupName="Lists">
  <body>
    <p><span class="bold">A list of things</span>: Element1, element2, element3, element4 element5.</p>
  </body>
 </Element>
</Content>

我想修改列表的内容,并将“,”替换为“&lt;,&gt;”。我有这段代码:

from lxml import etree as et
def replace_commas(file):
   parser = et.parse(str(file))
   root = parser.getroot()
   xpath_expr = "//Element[starts-with(@Ref,'List_') \
or @GroupName='Lists']/descendant::*"
   elements = root.xpath(xpath_expr)
   for element in elements:
       if element.text is not None or element.tail is not None:
          text = str(element.text)
          text = text.replace(',', '<,>')
          tail = str(element.tail)
          tail = tail.replace(',','<,>')
          element.text = text
          element.tail = tail
   tree = et.ElementTree(root)
   tree.write(file, pretty_print=True)

预期输出应为:

<Content Version="1.0" Name="Cont">
 <Element Ref="Text_4158" ElementType="ItISSomething" GroupName="Some_Content">
  <body>
    <p>Some content is here.</p>
  </body>
 </Element>
 <Element Ref="List_585" ElementType="ListElements" GroupName="Lists">
  <body>
    <p><span class="bold">A list of things</span>: Element1&lt;,&gt; element2&lt;,&gt; element3&lt;,&gt; element4 element5.</p>
  </body>
 </Element>
</Content>

但是我的结果是:

<Content Version="1.0" Name="Cont">
 <Element Ref="Text_4158" ElementType="ItISSomething" GroupName="Some_Content">
  <body>
    <p>Some content is here.</p>
  </body>
 </Element>
 <Element Ref="List_585" ElementType="ListElements" GroupName="Lists">
  <body>
    <p>None<span class="bold">A list of things</span>: Element1&lt;,&gt; element2&lt;,&gt; element3&lt;,&gt; element4 element5.</p>
  </body>
 </Element>
</Content>

在标签“p”和“span”之间获得“无”,应该没有任何内容。有什么问题?

我希望这个问题的更新有助于理解查询并找到解决方案。

更新:更正了def replace_commas(文件)中的冒号:以及et.ElementTree(root)的缩进。

另外,我发现mzjn建议的解决方案出错了。我在我的xml中有这个元素:

<Element Ref="List_222"ElementType="ListElements" GroupName="Lists">
  <body>
    <p><span class="bold">List: <span class="italic">Important elements</span></span>: El1 (prop1), el2 (prop2), el3 (prop3); with a special property.</p>
  </body>
</Element>

在这个元素中,我在重要元素的尾部得到NoneType,因为它的值为None。

我没有看到如何解决它。

2 个答案:

答案 0 :(得分:1)

如果元素的text属性为空(没有值),则返回内置常量None

第二个text元素的<p>属性为空。但是您使用text = str(element.text),这使text变量等于字符串'None'。这就是你在输出中看到的。

如果您分别针对每个元素检查texttail,它应该有效:

for element in elements:
    if element.text is not None:
        element.text = element.text.replace(',', '<,>')
    if element.tail is not None:
        element.tail = element.tail.replace(',', '<,>')

答案 1 :(得分:0)

看完之后我终于找到了空尾的解决方案。我没有检查一个元素是不是空的,而是检查了它是否是什么都不做,它是继续。:

for element in elements:
   if element.text is None:
       continue
   else:
       element.text = element.text.replace(',','<,>')
   if element.tail is None:
       continue
   else:
       element.tail = element.tail.replace(',','<,>')
   tree = et.ElementTree(root)
   tree.write(args.file,  pretty_print=True)

通过这个解决方案,我已经能够解决这个问题。