2009-10-16 22 views
31

Tôi đã cố gắng sử dụng SimpleXML, nhưng nó dường như không thích XML trông như thế này:Thư viện PHP để phân tích cú pháp XML bằng dấu hai chấm trong các tên thẻ?

<xhtml:div>sample <xhtml:em>italic</xhtml:em> text</xhtml:div> 

Vì vậy, những gì thư viện sẽ xử lý thẻ mà trông như thế (có dấu hai chấm trong họ)?

+1

Vui lòng đăng đoạn mã có liên quan. SimpleXML không nên có bất kỳ vấn đề với không gian tên. –

+0

Tôi cũng đã gặp vấn đề tương tự với 'SimpleXMLElement ($ data)' trả về null nếu dữ liệu xml có dấu hai chấm trong các thẻ. –

Trả lời

64

Giả sử bạn có một số xml như thế này.

<xhtml:div> 
    <xhtml:em>italic</xhtml:em> 
    <date>2010-02-01 06:00</date> 
</xhtml:div> 

Bạn có thể truy cập vào 'em' như thế này: $xml->children('xhtml', true)->div->em;

tuy nhiên, nếu bạn muốn trường ngày, này: $xml->children('xhtml', true)->div->date;sẽ không làm việc, bởi vì bạn đang bị mắc kẹt trong không gian tên xhtml.

bạn phải thực hiện 'em' một lần nữa để trở lại không gian tên mặc định:

$xml->children('xhtml', true)->div->children()->date; 
+1

không chắc chắn tại sao đây không phải là câu trả lời được chọn. Nhưng đối với bất cứ ai trong tương lai đây là một trong đó giải quyết câu hỏi/vấn đề của tôi! :) – daveomcd

7

Dấu hai chấm biểu thị vùng tên XML. DOM có hỗ trợ tốt cho không gian tên.

+0

SimpleXML có thể cũng vậy, nhưng OP đang tìm kiếm một thẻ "xhtml: div" thay vì chỉ "div". –

+0

SimpleXML có * một số nội dung * để xử lý, nhưng tôi vẫn không thể làm cho nó hoạt động đúng. – mpen

18

Nếu bạn muốn sửa chữa nó một cách nhanh chóng làm này (tôi làm khi tôi cảm thấy lười biếng):

// Will replace : in tags and attributes names with _ allowing easy access 
$xml = preg_replace('~(</?|\s)([a-z0-9_]+):~is', '$1$2_', $xml); 

Điều này sẽ chuyển đổi <xhtml: thành <xhtml_</xhtml: thành </xhtml_. Loại hacky và có thể thất bại nếu CDATA NameSpaced XML chứa các khối liên quan hoặc tên thẻ UNICODE nhưng tôi muốn nói rằng bạn thường an toàn khi sử dụng nó (chưa thất bại).

+4

Đó là bẩn. Nhưng tốt;) – joedevon

+0

Hoạt động nhưng nó hơi khó hiểu .. đã làm hỏng nội dung của các thẻ '' và thay đổi thời gian – supersan

2

Tôi không nghĩ nên loại bỏ đại tràng hoặc thay thế bằng thứ gì đó khác như một số người đã đề xuất. Bạn có thể dễ dàng truy cập các phần tử có tiền tố không gian tên. Bạn có thể truyền URL xác định không gian tên làm đối số cho phương thức children() hoặc chuyển tiền tố không gian tên và "true" cho phương thức children(). Cách tiếp cận thứ hai yêu cầu PHP 5.2 trở lên.

SimpleXMLElement::children

+0

Đây có phải là chính xác những gì Nathan Reed đề xuất trong câu trả lời tôi chấp nhận không? Tôi đồng ý rằng regex-fu là một hack bẩn, nhưng phải đi qua 'trẻ em()' chọn không phải là rất thú vị hoặc. – mpen

+0

Có, giống nhau. Tôi chỉ muốn chỉ ra rằng bạn cũng có thể truyền URL xác định vùng tên cho phương thức children() hoạt động với PHP 5 trở lên. IMHO, không cần phải làm một hack bẩn, khi có một phương pháp cốt lõi có sẵn. –

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