Vấn đề
Vấn đề với mã này là trong dòng đầu tiên:
$xmlTest = new SimpleXMLElement('<Test/>', 0, false, 'ws', true);
Trước khi làm bất cứ điều gì khác, chúng ta hãy đầu ra này như XML:
echo $xmlTest->asXML();
<?xml version="1.0"?>
<Test/>
Điều đó có ý nghĩa, chúng tôi đã tìm ra những gì chúng tôi đưa vào.
Hướng dẫn này khá mơ hồ về những gì đối số $ns
làm, nhưng trong trường hợp này nó không làm bất cứ điều gì hữu ích. Những gì nó làm là đặt bối cảnh cho đọc XML, sao cho ->foo
đề cập đến <ws:foo>
và ['bar']
đề cập đến ws:bar="..."
. Nó không làm bất cứ điều gì để thay đổi cấu trúc của chính XML.
Thiết lập một gốc Namespace
Để thiết lập một không gian tên trên phần tử gốc, chúng tôi chỉ phải bao gồm nó trong chuỗi của chúng tôi xác định phần tử gốc:
$xmlTest = new SimpleXMLElement('<ws:Test xmlns:ws="http://microsoft.com/wsdl/types/" />');
echo $xmlTest->asXML();
<?xml version="1.0"?>
<ws:Test xmlns:ws="http://microsoft.com/wsdl/types/"/>
Cho đến nay rất tốt ...
Namespaces Setting trên trẻ em
Tiếp theo, chúng ta hãy tỉnh táo kiểm tra những mã trong câu hỏi thực sự kết quả đầu ra (tôi đã thêm một số khoảng trắng để làm cho nó dễ đọc hơn):
<?xml version="1.0"?>
<Test>
<ws:somename2 xmlns:ws="http://microsoft.com/wsdl/types/">somevalue2</ws:somename2>
<ws:make xmlns:ws="ws">
<ws:model>foo</ws:model>
<ws:model>bar</ws:model>
</ws:make>
</Test>
OK, vì vậy đây tài liệu chứa hai tờ khai namespace:
xmlns:ws="http://microsoft.com/wsdl/types/"
trên các yếu tố somename2
xmlns:ws="ws"
trên các yếu tố make
, sau đó được thừa hưởng bởi các yếu tố model
gì sẽ xảy ra nếu chúng ta thêm phần tử gốc được sửa chữa của chúng tôi?
<?xml version="1.0"?>
<ws:Test xmlns:ws="http://microsoft.com/wsdl/types/">
<ws:somename2>somevalue2</ws:somename2>
<ws:make xmlns:ws="ws">
<ws:model>foo</ws:model>
<ws:model>bar</ws:model>
</ws:make>
</ws:Test>
mát, do đó yếu tố somename2
giờ đây thừa hưởng nét gian tên của nó từ phần tử gốc, và không tái khai báo nó. Nhưng có gì sai với make
và model
s? Hãy so sánh:
$xmlTest->addChild("ws:somename2", "somevalue2", 'http://microsoft.com/wsdl/types/');
$make = $xmlTest->addChild('ws:make', null, 'ws');
Đó số thứ ba được coi là các namespace URI, không chỉ là tiền tố. Vì vậy, khi chúng tôi đưa nó như là 'ws'
, SimpleXML giả định chúng tôi muốn khai báo URI không gian tên thực tế là ws
, vì vậy hãy thêm thuộc tính xmlns
để làm như vậy.
gì chúng tôi thực sự muốn là tất cả các yếu tố để được trong không gian tên giống nhau:
$xmlTest = new SimpleXMLElement('<ws:Test xmlns:ws="http://microsoft.com/wsdl/types/" />');
$xmlTest->addChild("ws:somename2", "somevalue2", 'http://microsoft.com/wsdl/types/');
$make = $xmlTest->addChild('ws:make', null, 'http://microsoft.com/wsdl/types/');
#$make->addAttribute('name','Ford', 'http://microsoft.com/wsdl/types/');
$make->addChild('ws:model', 'foo', 'http://microsoft.com/wsdl/types/');
$make->addChild('ws:model', 'bar', 'http://microsoft.com/wsdl/types/');
echo $xmlTest->asXML();
<?xml version="1.0"?>
<ws:Test xmlns:ws="http://microsoft.com/wsdl/types/">
<ws:somename2>somevalue2</ws:somename2>
<ws:make>
<ws:model>foo</ws:model>
<ws:model>bar</ws:model>
</ws:make>
</ws:Test>
Tuyệt vời, chúng tôi đã có đầu ra mong muốn của chúng tôi!
Tidying Up
Nhưng mã đó trông khá xấu, tại sao chúng ta phải lặp lại URI ở mọi nơi? Vâng, như xa như SimpleXML là có liên quan, không có nhiều sự lựa chọn: cùng một tiền tố có thể có nghĩa là những thứ khác nhau trong các phần khác nhau của tài liệu, vì vậy chúng tôi phải nói với nó những gì chúng ta muốn.
Những gì chúng ta thể làm là dọn dẹp mã của chúng tôi sử dụng một biến hoặc hằng số cho namespace URI, chứ không phải viết nó ra đầy đủ mỗi lần:
define('XMLNS_WS', 'http://microsoft.com/wsdl/types/');
$xmlTest = new SimpleXMLElement('<ws:Test xmlns:ws="' . XMLNS_WS . '" />');
$xmlTest->addChild("ws:somename2", "somevalue2", XMLNS_WS);
$make = $xmlTest->addChild('ws:make', null, XMLNS_WS);
#$make->addAttribute('name','Ford', XMLNS_WS);
$make->addChild('ws:model', 'foo', XMLNS_WS);
$make->addChild('ws:model', 'bar', XMLNS_WS);
Không có gì đặc biệt về tên XMLNS_WS
đây và nó có thể là một biến, hằng số lớp hoặc hằng số không gian tên. Mã chạy chính xác như nhau, nó chỉ dễ dàng hơn một chút trên mắt.
thực sự hoạt động, cảm ơn –
Vì vậy, thêm tiền tố vào tiền tố đã khắc phục sự cố :) –
Bạn có tìm thấy giải pháp nào khác ngoài giải pháp này không? – Hitesh