我正在使用PHP,必须构建SOAP
( 1.1 , document/literal )请求,该请求在内部包含XML消息soap:Body
标签。
我的第一个问题是我以前从未使用过此"协议"。
我的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字符串?
您可以使用元帅XML Serialializer,它更容易使用,而不是Domdocument和Simplexml。
然后您可以执行以下操作:
SOAPENVEVENEMAPPER.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);