9

我正在尝试使用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">

一个简单的命令失败如下:

$ 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

但这并不能完全满足我的需要。我的后续问题如下:

  1. 有没有办法只打印文本?我希望输出包含4.0.0在上面的示例中

  2. 似乎输出在大约 30 个字符后被截断。是否有可能获得完整的输出?这不会发生xmllint --xpath

4

2 回答 2

10
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

它不是很漂亮,但它避免了格式化假设和/或重新格式化输入 pom.xml 文件。

如果您出于某种原因需要删除“-SNAPSHOT”,请将上述结果通过| sed -e "s|-SNAPSHOT||".

于 2018-01-24T15:15:50.467 回答
9

用 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' -

返回这个:

<modelVersion>4.0.0</modelVersion>

如果您有时髦的格式(例如,xmlns 属性在它们自己的行上),请先通过格式化程序运行它:

cat pom.xml | xmllint --format - | sed '2 s/xmlns=".*"//g' | xmllint --xpath '/project/modelVersion' -
于 2015-05-01T00:19:19.493 回答