Python lxml 库在空标签中包含 None

Python lxml library includes None in empty tags

正如 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>

我想修改列表的内容,将“,”替换为“<,>”。我有这个代码:

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" 之间得到一个 None 并且应该没有任何内容。怎么了?

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

更新: 更正了 def replace_commas(file): 中的冒号和 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。

我不知道如何解决它。

如果一个元素的 text 属性 为空(没有值),它 returns 内置常量 None.

第二个 <p> 元素的 text 属性 为空。但是您使用 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(',', '<,>')

看了之后终于找到了解决空尾的办法。我没有检查元素是否为空,而是解决了检查 None 是否不执行任何操作,而是继续。:

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)

通过此修复,我已经能够解决问题。