2011-11-25 28 views
40

Tôi đang cố gắng truy vấn tệp xml được tạo bởi adium. xmlwf nói rằng nó cũng được hình thành. Bằng cách sử dụng tùy chọn gỡ lỗi của xmllint tôi nhận được thông tin sau:xmllint không truy vấn đúng cách với xpath

$ xmllint --debug doc.xml 
DOCUMENT 
version=1.0 
encoding=UTF-8 
URL=doc.xml 
standalone=true 
    ELEMENT chat 
    default namespace href=http://purl.org/net/ulf/ns/0.4-02 
    ATTRIBUTE account 
     TEXT 
     [email protected] 
    ATTRIBUTE service 
     TEXT compact 
     content=MSN 
    TEXT compact 
     content= 
    ELEMENT event 
     ATTRIBUTE type 

Mọi thứ dường như phân tích cú pháp tốt. Tuy nhiên, khi tôi cố gắng truy vấn ngay cả những điều đơn giản nhất, tôi không nhận được bất kỳ điều gì:

$ xmllint --xpath '/chat' doc.xml 
XPath set is empty 

Điều gì đang xảy ra? Chạy chính xác cùng một truy vấn đó bằng cách sử dụng xpath trả về kết quả chính xác (tuy nhiên không có dòng mới giữa các kết quả). Tôi đang làm điều gì đó sai hoặc là xmllint chỉ không hoạt động đúng?

Dưới đây là một phiên bản ẩn danh ngắn hơn của xml cho thấy các hành vi tương tự:

<?xml version="1.0" encoding="UTF-8" ?> 
<chat xmlns="http://purl.org/net/ulf/ns/0.4-02" account="[email protected]" service="MSN"> 
<event type="windowOpened" sender="[email protected]" time="2011-11-22T00:34:43-03:00"></event> 
<message sender="[email protected]" time="2011-11-22T00:34:43-03:00" alias="foo"><div><span style="color: #000000; font-family: Helvetica; font-size: 12pt;">hi</span></div></message> 
</chat> 
+0

bạn có thể vui lòng chia sẻ tệp doc.xml – rpg

Trả lời

67

tôi không sử dụng xmllint, nhưng tôi nghĩ rằng lý do XPath của bạn không hoạt động là vì doc.xml của bạn tệp đang sử dụng không gian tên mặc định (http://purl.org/net/ulf/ns/0.4-02).

Từ những gì tôi có thể thấy, bạn có 2 tùy chọn.

A. Sử dụng xmllint trong chế độ trình bao và khai báo không gian tên với tiền tố. Sau đó, bạn có thể sử dụng tiền tố đó trong XPath của mình.

xmllint --shell doc.xml 
    /> setns x=http://purl.org/net/ulf/ns/0.4-02 
    /> xpath /x:chat

B. Sử dụng local-name() để phù hợp với tên phần tử.

xmllint --xpath /*[local-name()='chat']

Bạn cũng có thể muốn sử dụng namespace-uri()='http://purl.org/net/ulf/ns/0.4-02' cùng với local-name() vì vậy bạn chắc chắn sẽ trở lại chính xác những gì bạn đang có ý định quay trở lại.

+2

Lưu ý ví dụ A. và B. sẽ không thành công nếu bạn không truy cập đường dẫn gốc, trong trường hợp này bạn cần dấu gạch chéo kép, ví dụ: xmllint --xpath "// * [local-name() = 'chat'] ". Xem http://stackoverflow.com/questions/27311314/how-to-get-the-tag-yweathercondition-from-yahoo-weather-rss-with-xmllint?noredirect=1#comment43085213_27311314 –

+0

@ Avt'W - Câu hỏi này/answer là đặc biệt về các không gian tên trong xmllint; không phải bất kỳ chủ đề XPath nào khác. Những gì '/' và '//' phù hợp là hoàn toàn không liên quan. –

+5

Hey, đó là một bình luận cho người đọc rằng sẽ có một trường hợp sử dụng hơi khác nhau, không phải là một nhà phê bình câu trả lời của bạn mà trả lời vấn đề một cách chính xác. Những người có vấn đề với không gian tên có thể là người mới và do đó tôi nghĩ rằng nó là giá trị chỉ ra rằng. –

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