我正在尝试使用处理大量的xml文件(maven poms)xmllint --xpath.通过一些试验和错误,我发现它由于这些文件中的错误默认命名空间声明而无法按预期工作,如下所示:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
Run Code Online (Sandbox Code Playgroud)
一个简单的命令失败如下:
$ echo $(xmllint --xpath '/project/modelVersion/text()' pom.xml )
XPath set is empty
Run Code Online (Sandbox Code Playgroud)
如果我删除了xmlns属性,则替换root元素如下:
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
Run Code Online (Sandbox Code Playgroud)
上一个命令给出了预期的输出:
$ echo $(xmllint --xpath '/project/modelVersion/text()' pom.xml )
4.0.0
Run Code Online (Sandbox Code Playgroud)
更改数百个pom文件不是一种选择,特别是因为maven本身并没有抱怨.
有没有办法xmllint用坏处理文件xmlns?
UPDATE
感谢Damien我能够取得一些进展:
$ ( echo setns x=http://maven.apache.org/POM/4.0.0; echo 'xpath /x:project/x:modelVersion/text()'; ) | xmllint --shell pom.xml
/ > setns x=http://maven.apache.org/POM/4.0.0
/ > xpath /x:project/x:modelVersion/text()
Object is a Node Set :
Set contains 1 nodes:
1 TEXT
content=4.0.0
Run Code Online (Sandbox Code Playgroud)
但这并不能满足我的需要.我的后续问题如下:
有没有办法只打印文字?我想4.0.0在上面的例子中包含输出
似乎输出在大约30个字符后被截断.是否有可能获得完整的输出?这不会发生xmllint --xpath
用sed剥离命名空间
给定于pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
</project>
Run Code Online (Sandbox Code Playgroud)
这个:
cat pom.xml | sed '2 s/xmlns=".*"//g' | xmllint --xpath '/project/modelVersion' -
Run Code Online (Sandbox Code Playgroud)
返回:
<modelVersion>4.0.0</modelVersion>
Run Code Online (Sandbox Code Playgroud)
如果你有时髦的格式(比如,xmlns属性在他们自己的行上),首先通过格式化程序运行它:
cat pom.xml | xmllint --format - | sed '2 s/xmlns=".*"//g' | xmllint --xpath '/project/modelVersion' -
Run Code Online (Sandbox Code Playgroud)
xmllint --xpath "/*[local-name() = 'project']/*[local-name() = 'parent']/*[local-name() = 'version']/text()" pom.xml
Run Code Online (Sandbox Code Playgroud)
对于顶级pom.xml:
xmllint --xpath "/*[local-name() = 'project']/*[local-name() = 'version']/text()" pom.xml
Run Code Online (Sandbox Code Playgroud)
它不是真的很漂亮,但它避免了格式化假设和/或重新格式化输入pom.xml文件.
如果由于某种原因需要剥离"-SNAPSHOT",请将上述结果通过| sed -e "s|-SNAPSHOT||".