如何通过 xpath 在 macOS 上 select 与 xml 分开匹配
How to select matches separately from xml by xpath on macOS
我想从匹配某个选择器的 XML 文件中获取所有文本内容。
我选择使用 XPath 选择器,因为我已经在我的 Mac 上安装了 xmllint(但它比版本 20909 旧,默认情况下显然具有我想要的行为)
$ xmllint --version
xmllint: using libxml version 20904
compiled with: Threads Tree Output Push Reader Patterns Writer SAXv1 FTP HTTP DTDValid HTML Legacy C14N Catalog XPath XPointer XInclude ICU ISO8859X Unicode Regexps Automata Expr Schemas Schematron Modules Debug Zlib
这是我的 xml
<?xml version="1.0" encoding="utf-8"?>
<xml>
<foo bar="baz">Lorem</foo>
<foo bar="baz">Ipsum</foo>
<foo bar="baz">Dolor</foo>
<foo bar="qux">Sit</foo>
<foo bar="baz">Amet</foo>
</xml>
我想获取具有某个属性值的foo元素的每个文本内容
$ xmllint --xpath '//foo[@bar="baz"]/text()' my.xml
LoremIpsumDolorAmet
输出不是换行分隔的,似乎也不是 NUL 分隔的:
$ xmllint --xpath '//foo[@bar="baz"]//text()' my.xml | od -A n -t x1
4c 6f 72 65 6d 49 70 73 75 6d 44 6f 6c 6f 72 41
6d 65 74
如何使用 macOS 呈现输出,使匹配项之间用换行符分隔?
可以用xpath --shell
按如下方式完成。
如果XML文件不是太大,可以优化加载到内存中。
cnt=$(xmllint --xpath 'count(//foo[@bar="baz"])' test.xml)
(for i in $(seq 1 $cnt); do echo "cat //foo[@bar='baz'][$i]/text()"; done) | xmllint --shell test.xml | grep -Ev '\/ [<>]( cat)?| -------'
结果:
Lorem
Ipsum
Dolor
Amet
最后没有 grep
它会产生
/ > cat //foo[@bar='baz'][1]/text()
-------
Lorem
/ > cat //foo[@bar='baz'][2]/text()
-------
Ipsum
/ > cat //foo[@bar='baz'][3]/text()
-------
Dolor
/ > cat //foo[@bar='baz'][4]/text()
-------
Amet
/ >
值得添加到答案中的不同版本
cnt=4; (for i in $(seq 1 $cnt); do echo "cd //foo[@bar='baz'][$i]/text()"; echo "cat"; done) | xmllint --shell test.xml | grep -Ev ' > (cat|cd)?'
没有 grep
/ > cd //foo[@bar='baz'][1]/text()
text > cat
Lorem
text > cd //foo[@bar='baz'][2]/text()
text > cat
Ipsum
text > cd //foo[@bar='baz'][3]/text()
text > cat
Dolor
text > cd //foo[@bar='baz'][4]/text()
text > cat
Amet
text >
我想从匹配某个选择器的 XML 文件中获取所有文本内容。
我选择使用 XPath 选择器,因为我已经在我的 Mac 上安装了 xmllint(但它比版本 20909 旧,默认情况下显然具有我想要的行为)
$ xmllint --version
xmllint: using libxml version 20904
compiled with: Threads Tree Output Push Reader Patterns Writer SAXv1 FTP HTTP DTDValid HTML Legacy C14N Catalog XPath XPointer XInclude ICU ISO8859X Unicode Regexps Automata Expr Schemas Schematron Modules Debug Zlib
这是我的 xml
<?xml version="1.0" encoding="utf-8"?>
<xml>
<foo bar="baz">Lorem</foo>
<foo bar="baz">Ipsum</foo>
<foo bar="baz">Dolor</foo>
<foo bar="qux">Sit</foo>
<foo bar="baz">Amet</foo>
</xml>
我想获取具有某个属性值的foo元素的每个文本内容
$ xmllint --xpath '//foo[@bar="baz"]/text()' my.xml
LoremIpsumDolorAmet
输出不是换行分隔的,似乎也不是 NUL 分隔的:
$ xmllint --xpath '//foo[@bar="baz"]//text()' my.xml | od -A n -t x1
4c 6f 72 65 6d 49 70 73 75 6d 44 6f 6c 6f 72 41
6d 65 74
如何使用 macOS 呈现输出,使匹配项之间用换行符分隔?
可以用xpath --shell
按如下方式完成。
如果XML文件不是太大,可以优化加载到内存中。
cnt=$(xmllint --xpath 'count(//foo[@bar="baz"])' test.xml)
(for i in $(seq 1 $cnt); do echo "cat //foo[@bar='baz'][$i]/text()"; done) | xmllint --shell test.xml | grep -Ev '\/ [<>]( cat)?| -------'
结果:
Lorem
Ipsum
Dolor
Amet
最后没有 grep
它会产生
/ > cat //foo[@bar='baz'][1]/text()
-------
Lorem
/ > cat //foo[@bar='baz'][2]/text()
-------
Ipsum
/ > cat //foo[@bar='baz'][3]/text()
-------
Dolor
/ > cat //foo[@bar='baz'][4]/text()
-------
Amet
/ >
值得添加到答案中的不同版本
cnt=4; (for i in $(seq 1 $cnt); do echo "cd //foo[@bar='baz'][$i]/text()"; echo "cat"; done) | xmllint --shell test.xml | grep -Ev ' > (cat|cd)?'
没有 grep
/ > cd //foo[@bar='baz'][1]/text()
text > cat
Lorem
text > cd //foo[@bar='baz'][2]/text()
text > cat
Ipsum
text > cd //foo[@bar='baz'][3]/text()
text > cat
Dolor
text > cd //foo[@bar='baz'][4]/text()
text > cat
Amet
text >