如何在没有名称空间的情况下将XML字符串附加到DOMDocument

时间:2017-12-20 18:32:03

标签: php xml web-services soap

我使用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字符串?

1 个答案:

答案 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);