如何在没有名称空间的情况下将XML字符串附加到DOMDocument
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在没有名称空间的情况下将XML字符串附加到DOMDocument相关的知识,希望对你有一定的参考价值。
我正在使用php并且必须构建一个包含SOAP
标记内的XML消息的soap:Body
(1.1,Document / Literal)请求。
我的第一个问题是我之前从未使用过这个“协议”。
我的XML消息非常复杂,所以我使用SimpleXMLElement
类来单独构建它。要编写SOAP
消息,我有两个XML字符串:
1- SOAP
结构。
<?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://www.w3.org/2003/05/soap-envelope">
<soap:Header></soap:Header>
<soap:Body>...</soap:Body>
</soap:Envelope>
2-我的自定义XML字符串
<eSocial xmlns="http://www.esocial.gov.br/schema/lote/eventos/envio/v2_2_02" grupo="1">
<envioLoteEventos>
<ideEmpregador tpInsc="1" nrInsc="0000000012"/>
<ideTransmissor tpInsc="1" nrInsc="0000000012"/>
<eventos>
<eSocial xmlns="http://www.esocial.gov.br/schema/evt/evtInfoEmpregador/v2_2_02">
<evtInfoEmpregador Id="8515">...</evtInfoEmpregador>
</eSocial>
</eventos>
</envioLoteEventos>
</eSocial>
- 我需要的是:
soap:Body
标签内的第二个字符串就像它一样。 - 我得到的:
soap:Body
中的第二个字符串,其中有一堆命名空间由DOMDocument
自动添加。
我正在使用的算法(不是完整代码):
$soapBodyElement = new SimpleXMLElement($soapBodyString);
$customMessageElement = new SimpleXMLElement($customMessageString);
// Some operations...
$domParent = dom_import_simplexml($soapBodyElement);
$domChild = dom_import_simplexml($customMessageElement);
$domDocument = $domParent->ownerDocument->importNode($domChild, true);
$domParent->appendChild($domDocument);
echo $domParent->ownerDocument->saveXML();
输出:
<soap:Envelope
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header/>
<soap:Body>
<eSocial xmlns="http://www.esocial.gov.br/schema/lote/eventos/envio/v2_2_02" xmlns:default="http://www.esocial.gov.br/schema/evt/evtInfoEmpregador/v2_2_02" xmlns:default1="http://www.w3.org/2000/09/xmldsig#" grupo="1">
<envioLoteEventos>
<ideEmpregador tpInsc="1" nrInsc="0000000012"/>
<ideTransmissor tpInsc="1" nrInsc="0000000012"/>
<eventos>
<default:eSocial xmlns="http://www.esocial.gov.br/schema/evt/evtInfoEmpregador/v2_2_02">
<default:evtInfoEmpregador Id="2550">...</default:evtInfoEmpregador>
</default:eSocial>
</eventos>
</envioLoteEventos>
</eSocial>
</soap:Body>
</soap:Envelope>
老实说,我不知道为什么添加了这个default
前缀(名称空间?)。
如何在没有此自动行为的情况下附加两个XML字符串?
答案
您可以使用Marshal XML Serializer,它比DOMDocument和SimpleXML更容易使用。
然后你可以做以下事情:
SoapEnvelopeMapper.php
use KingsonDeMarshalAbstractXmlMapper;
class SoapEnvelopeMapper extends AbstractXmlMapper {
/**
* @var AbstractXmlMapper
*/
private $messageMapper;
public function __construct(AbstractXmlMapper $messageMapper) {
$this->messageMapper = $messageMapper;
}
public function map($data) {
return [
'soap:Envelope' => [
$this->attributes() => [
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
'xmlns:soap' => 'http://www.w3.org/2003/05/soap-envelope',
],
'soap:Header' => null,
'soap:Body' => $this->item($this->messageMapper, $data),
]
];
}
}
SoapMessageMapper.php
use KingsonDeMarshalAbstractXmlMapper;
class SoapMessageMapper extends AbstractXmlMapper {
public function map($data) {
return [
'eSocial' => [
$this->attributes() => [
'xmlns' => 'http://www.esocial.gov.br/schema/lote/eventos/envio/v2_2_02',
'xmlns:default' => 'http://www.esocial.gov.br/schema/evt/evtInfoEmpregador/v2_2_02',
'xmlns:default1' => 'http://www.w3.org/2000/09/xmldsig#',
'grupo' => 1,
],
'envioLoteEventos' => [
'ideEmpregador' => [
$this->attributes() => [
'tpInsc' => 1,
'nrInsc' => '0000000012',
],
],
'ideTransmissor' => [
$this->attributes() => [
'tpInsc' => 1,
'nrInsc' => '0000000012',
],
],
],
'eventos' => [
'eSocial' => [
$this->attributes() => [
'xmlns' => 'http://www.esocial.gov.br/schema/evt/evtInfoEmpregador/v2_2_02',
],
'evtInfoEmpregador' => [
$this->attributes() => [
'Id' => 2550,
],
$this->data() => '...',
],
],
],
]
];
}
}
SoapResponse.php
$data = new stdClass();
$messageMapper = new SoapMessageMapper();
$envelopeMapper = new SoapEnvelopeMapper($messageMapper);
$xml = MarshalXml::serializeItem($envelopeMapper, $data);
以上是关于如何在没有名称空间的情况下将XML字符串附加到DOMDocument的主要内容,如果未能解决你的问题,请参考以下文章
如何在不删除旧文档的情况下将 XMLDocument 附加到 LocalStorage
如何在不导致复制的情况下将 char 数据附加到 std::vector
在没有 CSV 的情况下将 CSV 附加到 Python 中的电子邮件