如何使用xml2排除节点?以提取.docx正文排除表格为例
解决xml2提取docx正文并排除表格内容的问题
我之前处理docx文本提取时也遇到过一模一样的困扰——知道XPath 2.0的except能轻松排除节点,但xml2只支持XPath 1.0,得换个思路实现同样的效果。刚好可以给你分享下具体的实现步骤:
首先得明确docx解压后的XML结构:我们要处理的word/document.xml里,正文段落都用w:p标签包裹,而表格内容是嵌套在w:tbl(表格)→w:tr(行)→w:tc(单元格)下的w:p标签里。所以核心就是选中所有不在w:tbl节点范围内的w:p段落。
具体代码实现(以R的xml2包为例)
- 先加载包并读取解压后的XML文件:
library(xml2) # 读取docx解压后的document.xml doc <- read_xml("word/document.xml")
- 定义XML命名空间(docx的标签都带
w:前缀,必须指定命名空间才能正确匹配):
ns <- xml_ns(doc)
- 用XPath 1.0的语法替代
except,筛选出非表格内的段落:
# 关键XPath:所有w:p节点,且没有w:tbl类型的祖先节点 non_table_paragraphs <- xml_find_all(doc, ".//w:p[not(ancestor::w:tbl)]", ns) # 提取这些段落的文本内容 clean_body_text <- xml_text(non_table_paragraphs)
逻辑解释
XPath 1.0没有except运算符,但可以用not(ancestor::w:tbl)这个条件来反向筛选:
.//w:p会匹配XML里所有的段落节点[not(ancestor::w:tbl)]会排除掉那些父级/祖先级包含表格节点的段落,也就是表格单元格里的内容会被过滤掉
如果之后还需要排除其他特殊内容(比如文本框、批注里的段落),只需要在条件里追加and not(ancestor::w:textbox)这类规则就行。
内容的提问来源于stack exchange,提问作者Anonymous coward
相关产品推荐
相关产品推荐

