【问题标题】:Preserve newlines when pulling text from xml从 xml 中提取文本时保留换行符
【发布时间】:2015-08-28 21:20:28
【问题描述】:

我的 XML(从 .docx 中提取):

<w:p>
  <w:pPr>
    <w:pStyle w:val="Normal"/>
    <w:rPr/>
  </w:pPr>
  <w:r>
    <w:rPr/>
    <w:t>0 things and stuff</w:t>
  </w:r>
</w:p>
<w:p>
  <w:pPr>
    <w:pStyle w:val="Normal"/>
    <w:rPr/>
  </w:pPr>
  <w:r>
    <w:rPr/>
    <w:t>1 things and stuff</w:t>
  </w:r>
</w:p>

期望的输出:

0 things and stuff
1 things and stuff

实际输出:

0 things and stuff1 things and stuff

我尝试使用 lxml 包,希望他们的 tostring 方法与 pretty_print 相比,会产生比默认 xml 包更好的结果。

在研究这个问题时,我发现在 tostring 中使用 method='text' 会导致所有格式丢失。

我的代码:

tree = etree.fromstring(xml_content)
docx_text = etree.tostring(tree, method='text')

我尝试过使用 pretty_print=True、tostringlist 和 tounicode。我只是在寻找这个包中不存在的功能吗?

【问题讨论】:

    标签: python xml lxml


    【解决方案1】:

    您需要一个能够理解 docx xml 语义的所有业务逻辑的解析器,例如因为这两个文本行在不同的段落中,所以它们应该显示在不同的行中。

    您可以尝试自己执行此操作,但我建议使用 docx 之类的东西 - 或者至少查看源代码中的 getdocumenttext() 函数以了解解决此问题的一种方法。

    import os
    from docx import getdocumenttext
    from lxml import etree
    
    # get `xml_content` from word doc...    
    
    tree = etree.fromstring(xml_content)
    paragraphs = getdocumenttext(tree)
    print(os.linesep.join(paragraphs))
    # Result: 
    # 0 things and stuff
    # 1 things and stuff
    

    更新:有关完全可重现的示例,请参见下文

    import os
    from docx import getdocumenttext, opendocx
    from lxml import etree
    
    ## load the xml tree from word document ##
    # EITHER:
    tree = opendocx('/path/to/my/file.docx')
    
    # OR
    xml_content = """<?xml version="1.0" encoding="utf-8"?>
    <w:document mc:Ignorable="w14 w15 wp14" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mo="http://schemas.microsoft.com/office/mac/office/2008/main" xmlns:mv="urn:schemas-microsoft-com:mac:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape">
     <w:body>
      <w:p>
       <w:r>
        <w:t>0 things and stuff</w:t>
       </w:r>
      </w:p>
      <w:p>
       <w:r>
        <w:t>1 things and stuff</w:t>
       </w:r>
      </w:p>
     </w:body>
    </w:document>
    """
    tree = etree.fromstring(xml_content)
    ##
    
    paragraphs = getdocumenttext(tree)
    print(os.linesep.join(paragraphs))
    

    【讨论】:

    • 天哪。我想我爱你。谢谢!
    • 肯定的,很高兴我能帮上忙
    • 我实际上无法重现您的结果并且得到了paragraphs = [],没有任何异常或错误。请显示您所做操作的完整版本,例如您必须已导入 lxml 并且我必须修改示例 xml 字符串以正确读取它,那么您使用的是什么 xml 字符串?谢谢
    • 是的,我修改了我的示例以使用 astrimbu 已经在他的示例中使用的 xml_content var 和 etree,但你是对的,导入应该在那里......是的,我重新创建了 word docx 以包含标头,以使其使用 lxml 解析而不会出现错误。会更新。
    猜你喜欢
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    • 2013-12-20
    • 2014-11-26
    • 2017-03-17
    相关资源
    最近更新 更多