2017-12-20 5 views
0

なしのDOMDocumentにXML文字列を追加し、soap:Bodyタグの中にXMLメッセージが含まれていSOAP1.1ドキュメント/リテラル​​)要求を構築する必要があります。は、どのように私はPHPを使用している名前空間

私の最初の問題は、この「プロトコル」を使用したことがないことです。

私のXMLメッセージはかなり複雑ですので、私はSimpleXMLElementクラスを使ってそれを別々に構築しています。 SOAPメッセージを作成するには、2つの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タグ内の2番目の文字列。
  • 私が取得するもの: によって自動的に追加された複数の名前空間を持つsoap:Body内の2番目の文字列。私が使用している

アルゴリズム(ない完全なコード):

$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プレフィックスを知りませんを加えた。

この自動動作を行わない2つのXML文字列を追加するにはどうすればよいですか?

+0

DOMDocumentを使用してXMLファイルを最初から作成しようとしましたか? – DanielO

答えて

1

DOMDocumentとSimpleXMLのはるかに使いやすいMarshal XML Serializerを使用できます。

その後、あなたは次のことを行うことができます:

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); 
+0

ああ、私はこのプロジェクトを知らず、データ構造をXML文字列に変換するために自分のライブラリを作成しました( 'SimpleXMLElement'を使用しています)。私のlibの問題は、子要素を追加した後、相対属性を追加した後、次の行に追加された "soap:Envelope"要素の作成のために、SimpleXMLElementによってエラーメッセージが表示されます)。とにかく、私はmarshal-xml-serializerを見ていきます。 –

+0

プロジェクトはまったく新しいものです:)それは 'DOMDocument'を使って' SimpleXML'の制限に遭遇しません。あなたがそれを好きだと思います。コメント、提案は大歓迎です! – Kingson

関連する問題