我使用PHP并且必须构建一个SOAP
( 1.1 , Document / Literal )请求,其中包含{{}内的XML消息1}}标签。
我的第一个问题是我从未使用过这个"协议"之前。
我的XML消息非常复杂,所以我使用soap:Body
类来单独构建它。要撰写SimpleXMLElement
消息,我有两个XML字符串:
1- SOAP
结构。
SOAP
2-我的自定义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://www.w3.org/2003/05/soap-envelope">
<soap:Header></soap:Header>
<soap:Body>...</soap:Body>
</soap:Envelope>
<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>
前缀(名称空间?)。
如何在没有此自动行为的情况下附加两个XML字符串?
答案 0 :(得分:1)
你可以使用Marshal XML Serializer,它比DOMDocument和SimpleXML更容易使用。
然后你可以做到以下几点:
<强> SoapEnvelopeMapper.php 强>
use KingsonDe\Marshal\AbstractXmlMapper;
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 KingsonDe\Marshal\AbstractXmlMapper;
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);