2012-02-08 41 views
9

Tôi đang tìm kiếm tệp xml có các thuộc tính nhất định. Ví dụ, các file có chứa mẫu sau:Cách đơn giản nhất để thực hiện phân tích xml cơ bản từ dòng lệnh unix

<param-value> 
    <name>Hosts</name> 
    <description>some description</description> 
    <value></value> 
</param-value> 

cho tập tin như vậy, tôi muốn phân tích giá trị của thẻ khác, chẳng hạn như:

<param-value> 
    <name>Roles</name> 
    <description>some description</description> 
    <value>asdf</value> 
</param-value> 

Và in ra tên tập tin cùng với "asdf". Cách đơn giản nhất để thực hiện điều này từ dòng lệnh là gì?

Một cách tiếp cận mà tôi đã nghĩ đến là chỉ sử dụng grep với tùy chọn -l để lọc các tệp phù hợp, sau đó sử dụng xargs grep để trích xuất giá trị của Vai trò. Tuy nhiên, grep không hoạt động tốt với nhiều dòng regex. Tôi thấy một câu hỏi khác cho thấy nó có thể được thực hiện với các tùy chọn -Pzo, nhưng không có bất kỳ may mắn nhận được nó để làm việc trong trường hợp của tôi. Có cách tiếp cận đơn giản hơn không?

+0

Có bất kỳ lý do đặc biệt mà bạn không muốn sử dụng một ngôn ngữ kịch bản như perl? – Tom

+0

Không, giải pháp perl sẽ tuyệt vời, tốt nhất là một lớp lót nhỏ gọn, nhưng tôi không biết cách tốt nhất để viết về nó. – jonderry

+0

Sẽ rất hữu ích khi có một giải pháp chỉ chạy với các công cụ cơ bản nhất, xmlstarlet, xpath và mô-đun xpath của perl không được cài đặt trên hệ thống mà tôi sẽ thực hiện tìm kiếm. – jonderry

Trả lời

2

Cách đơn giản nhất đối với tôi là sử dụng Saxon từ dòng lệnh.

Dưới đây là ví dụ về cách sử dụng XPath on the command line. Điều này, kết hợp với một kịch bản shell, sẽ làm chính xác những gì bạn đang yêu cầu.

+0

Điều này trông giống như giải pháp di động nhất mà tôi là nhu cầu. –

0

Tôi đã hy vọng sẽ khắc phục sự cố của bạn cẩn thận hơn, nhưng tôi đã hết thời gian, xin lỗi.

Dù sao - perl có một số mô-đun rất tốt để đọc xml.

Cụ thể, bài viết sau, perl and xml on the command line, có thể là sở thích.

0

Tôi thường sử dụng số XML::XSH2 của Perl. Bạn có thể xử lý các tệp XML tương tác trong nó, hoặc kịch bản nó. Các kịch bản sẽ là một cái gì đó tương tự (chưa được kiểm tra):

for my $file in { glob "*.xml" } { 
    open $file ; 
    my $param_value = //param-value[name="Hosts"] ; 
    if $param_value echo $file $value/value ; 
} 
12

Lệnh linux sau đây sử dụng XPath để truy cập vào các giá trị nhất định trong tập tin XML

for xml in `find . -name "*.xml"` 
do 
echo $xml `xmllint --xpath "/param-value/value/text()" $xml`| awk 'NF>1' 
done 

Ví dụ đầu ra cho phù hợp với file XML:

./test1.xml asdf 
./test4.xml 1234 
1

Tôi đã làm việc ra một vài giải pháp bằng cách sử dụng chức năng perl/awk cơ bản (về cơ bản là phân tích cú pháp các thẻ của người nghèo). Nếu bạn thấy bất kỳ cải tiến nào chỉ sử dụng chức năng perl/awk cơ bản, hãy cho tôi biết. Tôi tránh đối phó với các biểu thức thông thường nhiều dòng bằng cách đặt cờ với một thẻ cụ thể. Loại vụng về nhưng nó hoạt động.

perl:

perl -ne '$h = 1 if m/Host/; $r = 1 if m/Role/; if ($h && m/<value>/) { $h = 0; print "hosts: ", $_ =~ /<value>(.*)</, "\n"}; if ($r && m/<value>/) { $r = 0; print "\nrole: ", $_ =~ /<value>(.*)</, "\n" }' 

awk:

awk '/Host/ {h = 1} /Role/ {r = 1} h && /<value>/ {h = 0; match($0, "<value>(.*)<", a); print "hosts: " a[1]} r && /<value>/ {r = 0; match($0, "<value>(.*)<", a); print "\nrole: " a[1]}' 
+4

Downvote, hãy giải thích lý do bạn downvoted. – jonderry

1
$ xmlstarlet ed -u /param-value/name -v Roles -u /param-value/value -v asdf data.xml 

<?xml version="1.0"?> 
<param-value> 
    <name>Roles</name> 
    <description>some description</description> 
    <value>asdf</value> 
</param-value> 
Các vấn đề liên quan