2012-07-23 56 views

Trả lời

8

Hãy thử điều này, nó không đẹp nhưng nó hoạt động :)

tôi chỉ xóa dòng chứa > từ stdout, cắt chuỗi để có được phần thứ hai sau khi = và xóa "

test=$(echo 'cat //body/value/@name' | xmllint --shell "test.xml" | grep -v ">" | cut -f 2 -d "=" | tr -d \"); 
echo $test 
+2

Sử dụng xmllint, do đó bạn không cần phải sử dụng REs để phân tích XML. Nhận ra bạn phải sử dụng RE để phân tích đầu ra của xmllint. – badp

+0

tại sao nó in ------- trước khi giá trị thuộc tính tên? làm thế nào để loại bỏ nó? –

23

Bạn cần sử dụng fn:string(), giá trị này sẽ trả về giá trị của đối số là xs:string. Trong trường hợp đối số của nó là một thuộc tính, nó sẽ trả về giá trị của thuộc tính là xs:string.

test=$(xmllint --xpath "string(//body/value/@name)" test.xml) 
+8

không may --xpath không được hỗ trợ trên nhiều cài đặt – Fergie

+0

http://stackoverflow.com/questions/11975862/xmllint-unknown-option-xpath – Dejan

+5

Chỉ hiển thị giá trị cho một phần tử duy nhất, có thể nhận được nhiều kết quả phù hợp ? –

4

Gần đây tôi đã phải chuyển giải pháp đơn giản ban đầu của mình bằng --xpath sang nền tảng thiếu tính năng này, vì vậy cũng phải áp dụng giải pháp "mèo". Điều này sẽ xử lý nhiều kết quả phù hợp, được thử nghiệm trên Ubuntu 12.04 và Solaris 11:

getxml() { # $1 = xml file, $2 = xpath expression 
    echo "cat $2" | xmllint --shell $1 |\ 
    sed -n 's/[^\"]*\"\([^\"]*\)\"[^\"]*/\1/gp' 
} 

ví dụ: trích xuất các tên cá thể từ cấu hình tên miền thủy tinh:

$ getxml /tmp/test.xml "//server[@node-ref]/@name" 
inst1 
inst2 

Chế độ hậu xử lý chỉ lấy tất cả các giá trị được trích dẫn phù hợp với nhu cầu của tôi (nhận bit cấu hình thủy tinh).

3

Một cách tiếp cận với một helper awk lệnh hỗ trợ nhiều thuộc tính (một phiên bản tinh gọn của ego's approach):

echo 'cat //*/@name' | xmllint --shell file | awk -F\" 'NR % 2 == 0 { print $2 }' 

Các awk lệnh:

  • chia xmllint 's đầu ra dòng vào các trường theo số " ký tự. (-F\")

    • Lưu ý rằng xmllint lại bình thường trích dẫn xung quanh các giá trị thuộc tính để "..." về sản lượng, ngay cả khi đầu vào có '...', vì vậy nó là đủ để chia bởi ".
  • chỉ xử lý các dòng được đánh số chẵn (NR %2 == 0), do đó lọc ra các dòng phân cách cat in một cách không đổi.

  • print $2 sau đó chỉ in trường thứ 2, là giá trị của mỗi thuộc tính mà không kèm theo "..." kèm theo.

Giả sử các XML mẫu sau trong file:

<body> 
    <value name="abc"></value> 
    <value name="def"></value> 
</body> 

sản lượng trên:

abc 
def 
+0

điều này làm việc hoàn hảo cho tôi, cảm ơn. Bạn cũng có một cách tốt đẹp để gán các giá trị cho các biến khác nhau. Giống như VAR_1 = $ (echo 'cat // */@ name' | xmllint --shell file | awk -F \ "'NR% 2 == 0 {print $ 2}')? – dieHellste

+0

@dieHellste: Bạn có thể đọc các dòng đầu ra thành các biến (hoặc trong một vòng lặp 'while' hoặc, trong Bash, thành một mảng với' read -a'), nếu bạn cần hướng dẫn thêm, hãy hỏi một câu hỏi mới. – mklement0

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