2015-02-12 73 views
5

我想用xmllint --xpath來處理大量的xml文件(maven poms)。隨着一些試驗和錯誤我想通了,它並不如預期,由於這些文件中的壞默認命名空間聲明,這是如下工作:強制xmllint忽略糟糕的xmlns

<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

UPDATE

感謝達米安我能夠取得一些進展:

$ (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

+0

這不是一個糟糕的命名空間。這是一個命名空間。這通常意味着您還需要在XPath查詢中使用名稱空間,但我不熟悉用於告訴您具體操作的工具的具體細節。 – 2015-02-12 09:16:14

+0

這很糟糕,因爲它導致xmllint失敗:)另外,因爲schmealocation是錯誤的。 – 2015-02-12 10:17:02

+1

「xmllint命名空間」上的一些簡單搜索出現了[這個問題](http://stackoverflow.com/questions/8264134/xmllint-failing-to-properly-query-with-xpath),它似乎顯示了兩種可能與*命名空間一起工作的方式。這種模式似乎是正確的。它表示,由URI「maven.apache.org/POM/4.0.0」標識的模式可以位於URL「http:// maven.apache.org/maven-v4_0_0.xsd」和這似乎是真的。 – 2015-02-12 10:39:07

回答

5

條的命名空間發生在pom.xml給出的Sed

<?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' - 
+0

謝謝,剛纔看到這個。我確實有xmlns屬性分佈在多行上,'--format'可能是一個很好的解決方案 – 2015-05-29 22:06:21

1
xmllint --xpath "/*[local-name() = 'project']/*[local-name() = 'parent']/*[local-name() = 'version']/text()" pom.xml 

它不是真正的漂亮,但它避免格式化假設和/或重新格式化輸入的pom.xml文件。

如果因爲某些原因需要剝離「-SNAPSHOT」,請將上述結果通過| sed -e "s|-SNAPSHOT||"進行管理。