2013-06-06 34 views
23

Tôi đang cố gắng để trích xuất các giá trị của một nút khỏi pom.xml:lệnh shell Native thiết lập để trích xuất giá trị nút từ XML

<?xml version="1.0" encoding="UTF-8"?> 
<project> 
    <parent> 
     <groupId>org.me.labs</groupId> 
     <artifactId>my-random-project</artifactId> 
     <version>1.5.0</version> 
    </parent> 
    ... 
</project> 

tôi cần phải trích xuất các artifactId và phiên bản từ XML bằng cách sử dụng lệnh shell. Tôi có các yêu cầu/quan sát sau đây:

  1. Kịch bản lệnh shell sẽ được thực hiện trong tệp lắp ráp chúng tôi sử dụng tại nơi làm việc, vì vậy tập lệnh càng nhỏ càng tốt.
  2. Vì nó sẽ được sử dụng trên nhiều hệ thống (thường là RHEL5), tôi đang tìm một thứ có thể chạy nguyên bản trên hình ảnh mặc định.
  3. Các thẻ giống như có thể xảy ra ở nơi khác trong pom, vì vậy tôi không thể đơn giản là awk cho các thẻ đó.

Tôi đã thử những điều sau đây:

  1. xpath công trình trên máy Mac của tôi, nhưng không có sẵn theo mặc định trên máy RHEL. Tương tự như vậy đối với xmllint --xpath, tôi đoán là chỉ khả dụng trên các phiên bản sau của xmllint, mà tôi không có và không thể thực thi.
  2. xmllint --pattern có vẻ đầy hứa hẹn, nhưng dường như tôi không thể nhận được kết quả từ xmllint --pattern '//project/parent/version' pom.xml (in toàn bộ XML) hoặc xmllint --stream --pattern '//project/parent/version' pom.xml (không có đầu ra).

Tôi nhận thấy đây là câu hỏi phổ biến ở đây trên SO, nhưng các điểm trên là lý do tôi không thể sử dụng các câu trả lời đó. TIA để được giúp đỡ.

Trả lời

14

tôi đã quản lý để giải quyết nó trong thời gian này với kịch bản khá unwiedly này sử dụng xmllint --shell.

echo "cat //project/parent/version" | xmllint --shell pom.xml | sed '/^\/ >/d' | sed 's/<[^>]*.//g' 

Nếu các nút XML có không gian tên các thuộc tính như pom.xml của tôi đã có, mọi thứ trở nên nặng hơn, về cơ bản giải nén các nút theo tên:

echo "cat //*[local-name()='project']/*[local-name()='parent']/*[local-name()='version']" | xmllint --shell pom.xml | sed '/^\/ >/d' | sed 's/<[^>]*.//g' 

Hy vọng nó giúp. Nếu bất cứ ai chỉ đơn giản là những biểu hiện này, tôi sẽ biết ơn.

+2

Ngoài ra, bạn có thể sử dụng: 'echo" cat // * [local-name() = 'project']/* [tên địa phương() = 'parent']/* [local-name() = 'version ']/text() "| xmllint --shell pom.xml | sed '/^\ />/d'', vì vậy bạn chỉ cần 'sed'-remove các công cụ xmllint shell –

+0

Nếu bạn có đủ' xmllint', thì bạn không cần công cụ '--shell' : 'xmllint --xpath/* [tên địa phương() ==" dự án "]/... 'pom.xml'. Phần 'local-name()' là những gì tôi đã bỏ lỡ cho kịch bản của mình. – Guss

13

--format chỉ được sử dụng để định dạng (thụt lề, v.v.) tài liệu. Bạn có thể làm điều đó bằng --xpath (thử nghiệm trong Ubuntu, libxml v20900):

$ xmllint --xpath "//project/parent/version/text()" pom.xml 
1.5.0 
+0

Như tôi đã nói, phiên bản của tôi của 'xmllint' dường như không ủng hộ 'tùy chọn --xpath'. Và tôi không muốn có cơ hội rằng nó sẽ có sẵn trên các hệ thống xây dựng của tôi. –

+0

Oh xin lỗi tôi đã không nhận thấy. python/libxml2 là một tùy chọn? – Salem

+1

Ngoài ra: 'xpath -q -e" // project/parent/version/text() "pom.xml' – Salem

3

Sử dụng text() XPath chức năng cung cấp cho bạn các giá trị phần tử, thay vì phải loại bỏ các thẻ XML:

echo "cat //project/parent/version/text()" | xmllint --shell pom.xml 
+0

Xin lỗi văn bản() không hoạt động cũng như không '/ value/text()' Bạn đang sử dụng phiên bản libxml2 nào? Tôi có 2.7.6 – Dejan

5

Tôi đến đây tìm kiếm một cách tốt đẹp để cạo một giá trị từ một trang web. Ví dụ sau có thể hữu ích cho những người (không giống như người đăng) có phiên bản xmllint hỗ trợ --xpath.

Tôi cần kéo phiên bản ổn định gần đây nhất của tệp elasticsearch .debfile và cài đặt nó. Các nhà bảo trì đã giúp đưa số phiên bản trong một khoảng thời gian với lớp "phiên bản".

version=`curl -s http://www.elasticsearch.org/download/ |\ 
xmllint --html --xpath '//span[@class="version"]/text()'\ 
2>/dev/null - `; 

Điều gì xảy ra:

Chúng tôi sử dụng curl -s tùy chọn (im lặng).

curl -s http://www.elasticsearch.org/download/ 

Chúng tôi sử dụng công tắc xmllint --html và --xpath. Những lập luận xpath (trong dấu nháy đơn)

'//span[@class="version"]/text()' 

... tìm kiếm một < khoảng > nút với các thuộc tính lớp (@class) "phiên bản", và trích xuất các giá trị văn bản (/ text()).

Vì xmllint là (ngạc nhiên!) Một linter, nó sẽ làm lu mờ về rác không thể tránh khỏi trong luồng html của bạn. Chúng tôi chỉ đạo stderr đến/dev/null theo cách thông thường:

2>/dev/null 

Cuối cùng, lưu ý "-" ở cuối của lệnh xmllint, mà nói với xmllint suối đến từ stdin.

+2

Karthik. V, đây không phải là câu trả lời hay cho bạn, nhưng câu hỏi của bạn cũng được đặt tên, vì vậy nó khá cao trong một tìm kiếm google. Tôi nghĩ tôi sẽ thêm điều này cho những người như tôi đang tìm kiếm câu trả lời nhanh và có các công cụ khác nhau. – lysdexia

-1

Bạn có thể thử

xmllint --xpath "/*[name()='project']/*[name()='groupId']/text()" pom.xml

Các vấn đề liên quan