您如何访问名称空间环境中的 SimpleXML 节点?
How do you access SimpleXML nodes in a namespace environment?
如何在命名空间环境中访问 PHP SimpleXML 节点?
我想务实地在<request>
下添加<param>value</param>
。不只是在字符串中编辑它。
$xml = \SimpleXMLElement(
'<?xml version="1.0" encoding="utf-8"?>' . PHP_EOL
. '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">' . PHP_EOL
. ' <soap:Body>' . PHP_EOL
. ' <Function xmlns="https://webservices.sveaekonomi.se/webpay">' . PHP_EOL
. ' <request />' . PHP_EOL
. ' </Function>' . PHP_EOL
. ' </soap:Body>' . PHP_EOL
. '</soap:Envelope>'
);
我尝试了以下操作:
#1
$xml->Envelope->Body->Function->request->addChild('param', 'value');
#2
$xml->children('https://webservices.sveaekonomi.se/webpay')->request->addChild('param', 'value');
#3
$xml->registerXPathNamespace('swp', 'https://webservices.sveaekonomi.se/webpay');
$xml->xpath('/swp:request')->addChild('param', 'value');
由于您正在处理 xml 一种方法是使用 xpath 和 local-name()
:
$xml = '<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Function xmlns="https://webservices.sveaekonomi.se/webpay">
<request/>
</Function>
</soap:Body>
</soap:Envelope>
';
$doc = new SimpleXMLElement($xml);
$destination = ($doc->xpath('//*[local-name()="request"]'));
$destination[0]->addChild('param', 'value');
echo $doc->asXML();
输出:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Function xmlns="https://webservices.sveaekonomi.se/webpay">
<request><param>value</param></request>
</Function>
</soap:Body>
</soap:Envelope>
你在这里犯了一些常见的错误,所以我将逐一逐一介绍。
让我们从第一次尝试开始:
$xml->Envelope->Body->...
SimpleXML 没有单独的文档 object,只有根元素 - 在本例中为 Envelope
。所以你不需要说 ->Envelope
,你已经在那里了。如果不涉及名称空间,您将编写:
$xml->Body->...
但是,object 不会 自动“select”该元素的名称空间,因此您必须立即调用 ->children()
,或者将你想要pre-select的命名空间传递给构造函数:
$xml->children('http://schemas.xmlsoap.org/soap/envelope/')->Body->...
// Or
$xml = new SimpleXMLElement($xmlString, 0, false, 'http://schemas.xmlsoap.org/soap/envelope/');
$xml->Body->...
考虑到这一点,我们可以:
$xml->children('http://schemas.xmlsoap.org/soap/envelope/')->Body->Function->...
这失败了,因为 Function
与 Body
不在同一个命名空间中。我喜欢的思路是the ->children()
method是一个“切换命名空间”的方法,所以我们切换到正确的命名空间继续:
$xml->children('http://schemas.xmlsoap.org/soap/envelope/')->Body
->children('https://webservices.sveaekonomi.se/webpay')->Function->request
->addChild('param', 'value');
这行得通!
你的第二次尝试犯了不同的错误:
$xml->children('https://webservices.sveaekonomi.se/webpay')->request->...
“children”方法不会让你跳到文档的深处——顾名思义,它给你 直接 children 的元素,而不是 grand-children,伟大的 grand-children,等等。 $xml
变量指向“信封”节点,并且没有 child 称为“请求”的节点。
没有 built-in 方法用于“任何后代”,除非使用 XPath...
虽然看起来完全不同,但你的第三次尝试实际上失败的原因是一样的:
$xml->registerXPathNamespace('swp', 'https://webservices.sveaekonomi.se/webpay');
$xml->xpath('/swp:request')->...
XPath 中的 /
运算符类似地表示“children of”; 是一个“任何后代”的运算符,即//
,所以你会nearly得到正确的结果:
$xml->registerXPathNamespace('swp', 'https://webservices.sveaekonomi.se/webpay');
$xml->xpath('//swp:request')->...
由于一个更微妙的原因,这将失败:SimpleXML 的 the xpath()
method 总是 returns 一个 数组 ,而不是 object,所以您必须要求该数组的第一个元素 ([0]
)。
所以有效的 XPath 代码是这样的:
$xml->registerXPathNamespace('swp', 'https://webservices.sveaekonomi.se/webpay');
$xml->xpath('//swp:request')[0]->addChild('param', 'value');
如何在命名空间环境中访问 PHP SimpleXML 节点?
我想务实地在<request>
下添加<param>value</param>
。不只是在字符串中编辑它。
$xml = \SimpleXMLElement(
'<?xml version="1.0" encoding="utf-8"?>' . PHP_EOL
. '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">' . PHP_EOL
. ' <soap:Body>' . PHP_EOL
. ' <Function xmlns="https://webservices.sveaekonomi.se/webpay">' . PHP_EOL
. ' <request />' . PHP_EOL
. ' </Function>' . PHP_EOL
. ' </soap:Body>' . PHP_EOL
. '</soap:Envelope>'
);
我尝试了以下操作:
#1
$xml->Envelope->Body->Function->request->addChild('param', 'value');
#2
$xml->children('https://webservices.sveaekonomi.se/webpay')->request->addChild('param', 'value');
#3
$xml->registerXPathNamespace('swp', 'https://webservices.sveaekonomi.se/webpay');
$xml->xpath('/swp:request')->addChild('param', 'value');
由于您正在处理 xml 一种方法是使用 xpath 和 local-name()
:
$xml = '<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Function xmlns="https://webservices.sveaekonomi.se/webpay">
<request/>
</Function>
</soap:Body>
</soap:Envelope>
';
$doc = new SimpleXMLElement($xml);
$destination = ($doc->xpath('//*[local-name()="request"]'));
$destination[0]->addChild('param', 'value');
echo $doc->asXML();
输出:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Function xmlns="https://webservices.sveaekonomi.se/webpay">
<request><param>value</param></request>
</Function>
</soap:Body>
</soap:Envelope>
你在这里犯了一些常见的错误,所以我将逐一逐一介绍。
让我们从第一次尝试开始:
$xml->Envelope->Body->...
SimpleXML 没有单独的文档 object,只有根元素 - 在本例中为 Envelope
。所以你不需要说 ->Envelope
,你已经在那里了。如果不涉及名称空间,您将编写:
$xml->Body->...
但是,object 不会 自动“select”该元素的名称空间,因此您必须立即调用 ->children()
,或者将你想要pre-select的命名空间传递给构造函数:
$xml->children('http://schemas.xmlsoap.org/soap/envelope/')->Body->...
// Or
$xml = new SimpleXMLElement($xmlString, 0, false, 'http://schemas.xmlsoap.org/soap/envelope/');
$xml->Body->...
考虑到这一点,我们可以:
$xml->children('http://schemas.xmlsoap.org/soap/envelope/')->Body->Function->...
这失败了,因为 Function
与 Body
不在同一个命名空间中。我喜欢的思路是the ->children()
method是一个“切换命名空间”的方法,所以我们切换到正确的命名空间继续:
$xml->children('http://schemas.xmlsoap.org/soap/envelope/')->Body
->children('https://webservices.sveaekonomi.se/webpay')->Function->request
->addChild('param', 'value');
这行得通!
你的第二次尝试犯了不同的错误:
$xml->children('https://webservices.sveaekonomi.se/webpay')->request->...
“children”方法不会让你跳到文档的深处——顾名思义,它给你 直接 children 的元素,而不是 grand-children,伟大的 grand-children,等等。 $xml
变量指向“信封”节点,并且没有 child 称为“请求”的节点。
没有 built-in 方法用于“任何后代”,除非使用 XPath...
虽然看起来完全不同,但你的第三次尝试实际上失败的原因是一样的:
$xml->registerXPathNamespace('swp', 'https://webservices.sveaekonomi.se/webpay');
$xml->xpath('/swp:request')->...
XPath 中的 /
运算符类似地表示“children of”; 是一个“任何后代”的运算符,即//
,所以你会nearly得到正确的结果:
$xml->registerXPathNamespace('swp', 'https://webservices.sveaekonomi.se/webpay');
$xml->xpath('//swp:request')->...
由于一个更微妙的原因,这将失败:SimpleXML 的 the xpath()
method 总是 returns 一个 数组 ,而不是 object,所以您必须要求该数组的第一个元素 ([0]
)。
所以有效的 XPath 代码是这样的:
$xml->registerXPathNamespace('swp', 'https://webservices.sveaekonomi.se/webpay');
$xml->xpath('//swp:request')[0]->addChild('param', 'value');