从 xml 中提取文本时保留换行符
Preserve newlines when pulling text from xml
我的 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 包,希望他们使用 pretty_print 的 tostring 方法会产生比默认 xml 包更好的结果。
在研究问题时,我发现在 tostring 中使用 method='text' 会导致所有格式丢失的解释。
我的代码:
tree = etree.fromstring(xml_content)
docx_text = etree.tostring(tree, method='text')
我试过使用 pretty_print=True、tostringlist 和 tounicode。我只是在寻找此软件包中不存在的功能吗?
您需要一个能够理解 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))
我的 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 包,希望他们使用 pretty_print 的 tostring 方法会产生比默认 xml 包更好的结果。
在研究问题时,我发现在 tostring 中使用 method='text' 会导致所有格式丢失的解释。
我的代码:
tree = etree.fromstring(xml_content)
docx_text = etree.tostring(tree, method='text')
我试过使用 pretty_print=True、tostringlist 和 tounicode。我只是在寻找此软件包中不存在的功能吗?
您需要一个能够理解 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))