强制 xmllint 忽略错误的默认 xmlns
Force xmllint to ignore bad default xmlns
我正在尝试使用 xmllint --xpath
处理大量 xml 个文件 (maven poms)。经过反复试验,我发现由于这些文件中的默认命名空间声明错误,它无法按预期工作,如下所示:
<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">
一个简单的命令失败如下:
$ echo $(xmllint --xpath '/project/modelVersion/text()' pom.xml )
XPath set is empty
如果我去掉 xmlns 属性,替换根元素如下:
<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">
前面的命令给出了预期的输出:
$ echo $(xmllint --xpath '/project/modelVersion/text()' pom.xml )
4.0.0
更改数百个 pom 文件不是一种选择,尤其是因为 maven 本身不会抱怨。
有没有办法让 xmllint
处理包含错误 xmlns
的文件?
更新
多亏了 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
但这并不能完全满足我的需要。我的后续问题如下:
有没有办法只打印文本?我希望输出包含上例中的 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>
这个:
cat pom.xml | sed '2 s/xmlns=".*"//g' | xmllint --xpath '/project/modelVersion' -
returns 这个:
<modelVersion>4.0.0</modelVersion>
如果你有时髦的格式(比如,xmlns 属性在它们自己的行上),运行 它首先通过格式化程序:
cat pom.xml | xmllint --format - | sed '2 s/xmlns=".*"//g' | xmllint --xpath '/project/modelVersion' -
xmllint --xpath "/*[local-name() = 'project']/*[local-name() = 'parent']/*[local-name() = 'version']/text()" pom.xml
顶级pom.xml:
xmllint --xpath "/*[local-name() = 'project']/*[local-name() = 'version']/text()" pom.xml
它不是很漂亮,但它避免了格式假设 and/or 重新格式化输入 pom.xml 文件。
如果您出于某种原因需要删除“-SNAPSHOT”,请通过 | sed -e "s|-SNAPSHOT||"
.
传递上述结果
我正在尝试使用 xmllint --xpath
处理大量 xml 个文件 (maven poms)。经过反复试验,我发现由于这些文件中的默认命名空间声明错误,它无法按预期工作,如下所示:
<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">
一个简单的命令失败如下:
$ echo $(xmllint --xpath '/project/modelVersion/text()' pom.xml )
XPath set is empty
如果我去掉 xmlns 属性,替换根元素如下:
<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">
前面的命令给出了预期的输出:
$ echo $(xmllint --xpath '/project/modelVersion/text()' pom.xml )
4.0.0
更改数百个 pom 文件不是一种选择,尤其是因为 maven 本身不会抱怨。
有没有办法让 xmllint
处理包含错误 xmlns
的文件?
更新
多亏了 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
但这并不能完全满足我的需要。我的后续问题如下:
有没有办法只打印文本?我希望输出包含上例中的
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>
这个:
cat pom.xml | sed '2 s/xmlns=".*"//g' | xmllint --xpath '/project/modelVersion' -
returns 这个:
<modelVersion>4.0.0</modelVersion>
如果你有时髦的格式(比如,xmlns 属性在它们自己的行上),运行 它首先通过格式化程序:
cat pom.xml | xmllint --format - | sed '2 s/xmlns=".*"//g' | xmllint --xpath '/project/modelVersion' -
xmllint --xpath "/*[local-name() = 'project']/*[local-name() = 'parent']/*[local-name() = 'version']/text()" pom.xml
顶级pom.xml:
xmllint --xpath "/*[local-name() = 'project']/*[local-name() = 'version']/text()" pom.xml
它不是很漂亮,但它避免了格式假设 and/or 重新格式化输入 pom.xml 文件。
如果您出于某种原因需要删除“-SNAPSHOT”,请通过 | sed -e "s|-SNAPSHOT||"
.