我有一个文件多次xml
包含该标签。</w:rPr>
它是这样使用的
<w:rPr>
TO REMOVE
</w:rPr>
然而,标签本身之间的内容有时是不同的。有没有办法使用 sed 或其他东西来删除<w:rPr>
和之间的所有内容</w:rPr>
,然后也删除两个标签?
相关命名空间
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
以及文件本身(格式化的、有效的 XML)
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:lvl w:ilvl="0">
<w:rPr>
TO REMOVE
</w:rPr>
<w:rPx>
<w:rFonts w:ascii="Symbol" w:hAnsi="Symbol" w:hint="default"/>
</w:rPx>
</w:lvl>
</root>
答案1
长话短说
请,从不使用sed为了这个任务!
每次你使用sed
forhtml
或xml
,你就会杀死一只小猫
这是一个任务xmlstarlet
(一个合适的 XML 解析器)和他的朋友路径, 像这样:
xmlstarlet ed \
-L \
-N w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" \
-d '//w:rPr' file.xml
一些解释:
-L
编辑文件在飞行中喜欢sed -i
-N
设置XML命名空间, 如果需要的话-d
删除匹配xpath
表达式的节点
查看xmlstarlet edit --help
使用basex
纯 XQuery 解决方案:
$ cat XQuery
declare namespace w = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
copy $input := doc("/dev/stdin")
modify delete node $input//w:rPr
return $input
$ basex XQuery < file.xml
使用XQuery
和xidel
:
xidel --xml --xquery '
declare namespace w = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
x:replace-nodes(//w:rPr, ())
' file.xml
理论 :
根据编译理论,XML/HTML 无法使用基于的正则表达式进行解析有限状态机。由于 XML/HTML 的层次结构,您需要使用下推自动机并操纵左旋受体使用类似工具的语法亚克力。
realLife©®™ 日常工具壳:
您可以使用以下其中一项:
- xmllint通常默认安装
libxml2
xpath1 - xmlstarlet可以编辑、选择、转换...默认未安装,XPath1
- 路径通过 Perl 的模块 XML::XPath、XPath1 安装
- 基础X默认情况下未安装,包
basex
,完整的 XQuery 3.1 - 希德尔XPath3,部分 XQuery 3(无更新)
- 撒克逊林特我自己的项目,@Michael Kay 的 Saxon-HE Java 库 XPath3 的包装
或者您可以使用高级语言和适当的库,我认为:
Python的lxml
( from lxml import etree
)
珀尔的XML::LibXML
,XML::XPath
,XML::Twig::XPath
,HTML::TreeBuilder::XPath