2012-01-26 13 views
6

Tôi có tệp pom.xml điển hình và muốn in nhómId, artifactId và phiên bản, được phân cách bằng dấu hai chấm. Tôi nghĩ rằng XMLStarlet là công cụ thích hợp cho điều đó. Tôi đã thử nhiều cách, nhưng tôi luôn nhận được một dòng trống.XMLStarlet không chọn bất kỳ thứ gì

xml sel -t -m project -v groupId -o : -v artifactId -o : -v version pom.xml 

sản lượng dự kiến:

org.something.apps:app-acct:5.4 

đầu ra thật: trống dòng

Thậm chí nếu tôi cố gắng in chỉ là groupId Tôi nhận được gì:

Tôi chắc chắn rằng công cụ nhìn thấy các yếu tố bởi vì tôi có thể liệt kê chúng mà không có vấn đề:

xml el pom.xml 

in như sau (chính xác):

project 
project/modelVersion 
project/parent 
project/parent/groupId 
project/parent/artifactId 
project/parent/version 
project/groupId 
project/artifactId 
project/version 
project/packaging 

Có chuyện gì vậy?

Dưới đây là phiên bản cắt giảm của 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> 

    <parent> 
     <groupId>org.something</groupId> 
     <artifactId>base</artifactId> 
     <version>1.16</version> 
    </parent> 

    <groupId>org.something.apps</groupId> 
    <artifactId>app-acct</artifactId> 
    <version>5.4</version> 
    <packaging>war</packaging> 

</project> 

Trả lời

28

Thật không may, XMLStarlet là rất kén chọn về không gian tên mặc định. Nếu tài liệu có nó tuyên bố (xmlns=), bạn phải khai báo nó cho XMLStarlet quá, và tiền tố các yếu tố có tên mà bạn đã chọn (xem here):

xml sel -N của tôi = http://maven.apache.org/POM/4.0.0 -t - m của tôi: dự án -v tôi: groupId -o: -v tôi: artifactId -o: -v tôi: phiên bản pom.xml

Chạy lệnh trên đưa ra kết quả mong muốn:

org.something.apps:app-acct:5.4 

Tuy nhiên, nếu tài liệu KHÔNG có de không gian tên lỗi được khai báo (hoặc không gian tên có một URL hơi khác), lệnh trên sẽ KHÔNG hoạt động, đó là một PITA thực. Một giải pháp phổ quát hơn là xóa khai báo không gian tên mặc định trước khi chọn các phần tử. Kể từ XMLStarlet 1.3.1, việc chuyển đổi định dạng XML sang PYX và ngược lại loại bỏ các khai báo không gian tên:

xml pyx pom.xml | xml p2x | xml sel -t -m dự án -v groupId -o: -o -v artifactId: -v phiên bản 2> nul

UPDATE (2014/02/12): như của XMLStarlet 1.4.2 các hộp pyx < -> Chuyển đổi XML là cố định (không loại bỏ các khai báo không gian tên), vì vậy lệnh trên sẽ KHÔNG hoạt động (nhờ có Peter Gluck cho đầu). Sử dụng lệnh sau để thay thế:

xml pyx pom.xml | grep -v^A | xml p2x | xml sel -t -m project -v groupId -o: -v artifactId -o: -v phiên bản

Lưu ý: grep trên loại bỏ TẤT CẢ các thuộc tính khỏi tài liệu, không chỉ khai báo không gian tên. Đối với trường hợp cụ thể này (chọn giá trị phần tử từ pom.xml nơi các phần tử có các vùng tên không mặc định không được mong đợi) nó là Ok, nhưng với một XML chung, bạn sẽ loại bỏ chỉ các khai báo không gian tên mặc định và không có gì khác:

xml pyx pom.xml | grep -v "^ Axmlns" | xml p2x | dự án xml sel -t -m -v groupId -o: -o -v artifactId: phiên bản -v


Note (lỗi thời): chuyển hướng lỗi (2>nul) là cần thiết để ẩn các khiếu nại về (bây giờ) chưa biết xsi namespace:

-: 1,28: namespace prefix xsi cho schemaLocation về dự án không được định nghĩa

Một cách khác để loại bỏ các khiếu nại là để loại bỏ các schemaLocation tại cống (thực tế, lệnh này loại bỏ tất cả các thuộc tính từ tài liệu PYX, không chỉ xsi: schemaLocation):

xml pyx pom.xml | grep -v^A | xml p2x | xml sel -t -m project -v groupId -o: -v artifactId -o: -v phiên bản

+0

Nhận xét của bạn về các phần tử tiền tố với (bí danh cho?) Không gian tên được khai báo là sự khác biệt quan trọng đối với tài liệu được liên kết. – chernevik

5

Thủ thuật XML-> PYX -> XML không hoạt động đối với tôi (sử dụng phiên bản XMLStarlet 1.4.2) . Tuy nhiên, XMLStarlet documentation chứa tiện dụng sed lệnh này mà loại bỏ tờ khai gian tên từ một tài liệu XML:

sed -e 's/ xmlns.*=".*"//g' 

Đó làm việc. Đối với câu hỏi ban đầu, cú pháp sẽ là:

cat pom.xml | sed -e 's/ xmlns.*=".*"//g' | xml sel -t -m project -v groupId -o : -v artifactId -o : -v version 
+0

Cảm ơn bạn đã cập nhật về thay đổi trong PYX -> chuyển đổi XML. Điều này có nghĩa là dòng lệnh cuối cùng (với grep -v^A) bây giờ là dòng lệnh ưu tiên. Tuy nhiên, không nên sử dụng sed/grep/awk vv trên XML chung: nó hoạt động cho ví dụ đơn giản cụ thể trong tài liệu (và ví dụ đơn giản của tôi), nhưng nó có thể dễ dàng tạo một tài liệu XML không hợp lệ. Ví dụ: chạy sed "tiện dụng" này: a = "X"; trả lại a; sẽ dẫn đến điều này: uk4sx