2017-10-20 118 views
0

正如mzjn所提示的,我正在改变整个问题并试图简化它。Python lxml库中没有空标记

我有这样的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” 和“跨度之间的无“而且什么都不应该。哪里不对?

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

更新:更正了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,因为它得到值无。

我看不到如何解决它。

+0

你可以添加理想的情况吗? – Jonathan

+0

我已经添加了理想的情况下,这将与没有None值的空元素,我已经添加了一些关于我的小原因研究的信息。但是我还没有找到任何。 – TMikonos

+0

请简化问题并创建[mcve]。 – mzjn

回答

1

如果元素的text属性为空(没有值),则返回内置常量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(',', '<,>') 
+0

我得到了element.tail中的错误,因为我得到一个NoneType对象没有属性替换。 – TMikonos

+0

'if element.tail不是None:'是为了防止这样的错误。我无法解释你为什么得到这个错误。您需要提供更多信息。 – mzjn

+0

它给我一个空的元素:

。这很奇怪。我不知道哪里看起来更多。 – TMikonos

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) 

用此修复程序围绕我已经能够解决这个问题。