phpxmlsimplexml

build XML with PHP and structure defined


I´m trying to create a xml with this structure:

<pt:request xmlns:pt="urn:logalty:schemas:core:1.0" xmlns:identity="urn:logalty:schemas:core:identity:1.0" xmlns:process_meta="urn:logalty:schemas:process:meta:1.0" xmlns:ptforms="urn:logalty:schemas:forms:1.0" xmlns:request_meta="urn:logalty:schemas:request:meta:1.0">
    <pt:request_meta>
        <request_meta:service>PT0005_ACCEPTANCEXPRESS</request_meta:service>
        <request_meta:time2close unit="d" value="28"/>
        <request_meta:time2save unit="d" value="1825"/>
        <request_meta:lopd>0</request_meta:lopd>
        <request_meta:retryprotocol>3</request_meta:retryprotocol>
        <request_meta:synchronous>false</request_meta:synchronous>
        <request_meta:tsa>0</request_meta:tsa>
        <request_meta:userdefined name="LGT_SDKJava">4.13.2</request_meta:userdefined>
    </pt:request_meta>
    <pt:process_meta>
        <process_meta:generator>generator</process_meta:generator>
        <process_meta:language>es-ES</process_meta:language>
        <process_meta:receivers>
            <identity:receiver receiver-id="1">
                <identity:personalData>
                    <identity:firstname>first</identity:firstname>
                    <identity:middlename>middle</identity:middlename>
                    <identity:lastname1>last1</identity:lastname1>
                    <identity:lastname2>last2</identity:lastname2>
                </identity:personalData>
                <identity:contact>
                    <identity:uuid>uuid1</identity:uuid>
                    <identity:phone>phone</identity:phone>
                    <identity:mobile>mobile</identity:mobile>
                    <identity:fax>fax</identity:fax>
                    <identity:email>email@logalty.com</identity:email>
                </identity:contact>
                <identity:legalIdentity>
                    <identity:type>DNI</identity:type>
                    <identity:jurisdictionCountry>ESP</identity:jurisdictionCountry>
                    <identity:issuer>issuer</identity:issuer>
                    <identity:id>id</identity:id>
                    <identity:certificate>certificate</identity:certificate>
                </identity:legalIdentity>
                <identity:binarycontentrules>
                    <identity:binarycontentrule binary-content-group-id="1" binarycontentrule-id="1">
                        <request_meta:signMethods>
                            <request_meta:signMethod>SMS_VOICE</request_meta:signMethod>
                        </request_meta:signMethods>
                    </identity:binarycontentrule>
                </identity:binarycontentrules>
            </identity:receiver>
        </process_meta:receivers>
        <process_meta:subject>subject</process_meta:subject>
        <process_meta:body>body</process_meta:body>
        <process_meta:url>LOGALTY_DIRECT_ACCESS_DOC_IN_FRAME</process_meta:url>
        <process_meta:email>sender@example.com</process_meta:email>
        <process_meta:userdefined name="name">value</process_meta:userdefined>
    </pt:process_meta>

but my problem it´s, that in all my key from array my code add pt, and i don´t know why.

my result:

<?xml version="1.0"?>
<pt:request xmlns:pt="urn:logalty:schemas:core:1.0" xmlns:identity="urn:logalty:schemas:core:identity:1.0" xmlns:process_meta="urn:logalty:schemas:process:meta:1.0" xmlns:ptforms="urn:logalty:schemas:forms:1.0" xmlns:request_meta="urn:logalty:schemas:request:meta:1.0">
    <pt:request_meta>
        <pt:service>instalacion_id_1</pt:service>
        <pt:time2close unit="d" value="28"/>
        <pt:time2save unit="d" value="1825"/>
        <pt:lopd>0</pt:lopd>
        <pt:retryprotocol>3</pt:retryprotocol>
        <pt:synchronous/>
        <pt:tsa>0</pt:tsa>
        <pt:userdefined name="php">8.1.6</pt:userdefined>
    </pt:request_meta>
    <pt:process_meta>
        <pt:generator>generator</pt:generator>
        <pt:language>es-ES</pt:language>
        <pt:receivers>
            <pt:receiver receiver-id="1">
                <pt:personalData>
                    <pt:firstname>first</pt:firstname>
                    <pt:middlename>middle</pt:middlename>
                    <pt:lastname1>last1</pt:lastname1>
                    <pt:lastname2>last2</pt:lastname2>
                </pt:personalData>
                <pt:contact>
                    <pt:uuid>uuid1</pt:uuid>
                    <pt:phone>phone</pt:phone>
                    <pt:mobile>mobile</pt:mobile>
                    <pt:fax>fax</pt:fax>
                    <pt:email>email@logalty.com</pt:email>
                </pt:contact>
                <pt:legalIdentity>
                    <pt:type>DNI</pt:type>
                    <pt:jurisdictionCountry>ESP</pt:jurisdictionCountry>
                    <pt:issuer>issuer</pt:issuer>
                    <pt:id>id</pt:id>
                    <pt:certificate>certificate</pt:certificate>
                </pt:legalIdentity>
                <pt:binarycontentrules>
                    <pt:binarycontentrule binary-content-group-id="1" binarycontentrule-id="1">
                        <pt:signMethods>
                            <pt:signMethod>SMS_VOICE</pt:signMethod>
                        </pt:signMethods>
                    </pt:binarycontentrule>
                </pt:binarycontentrules>
            </pt:receiver>
        </pt:receivers>
        <pt:subject>subject</pt:subject>
        <pt:body>body</pt:body>
        <pt:url>LOGALTY_DIRECT_ACCESS_DOC_IN_FRAME</pt:url>
        <pt:email>sender@example.com</pt:email>
        <pt:userdefined name="name">value</pt:userdefined>
    </pt:process_meta>
</pt:request>

my arrays, data its:

$logalty_data_header = [
                    'request_meta:service' => 'instalacion_id_'.$id,
                    'request_meta:time2close unit="d" value="28"' => "",
                    'request_meta:time2save unit="d" value="1825"' => "",
                    'request_meta:lopd' => 0,
                    'request_meta:retryprotocol' => 3,
                    'request_meta:synchronous' => false,
                    'request_meta:tsa' => 0,
                    'request_meta:userdefined name="php"' => '8.1.6',
                ]; 
                $logalty_data_process = array(
                    'process_meta:generator' => 'generator',
                    'process_meta:language' => 'es-ES',
                    'process_meta:receivers' => array(
                        'identity:receiver receiver-id="1"' => array(
                            'identity:personalData' => array(
                                'identity:firstname' => 'first',
                                'identity:middlename' => 'middle',
                                'identity:lastname1' => 'last1',
                                'identity:lastname2' => 'last2',
                            ),
                            'identity:contact' => array(
                                'identity:uuid' => 'uuid1',
                                'identity:phone' => 'phone',
                                'identity:mobile' => 'mobile',
                                'identity:fax' => 'fax',
                                'identity:email' => 'email@logalty.com',
                            ),
                            'identity:legalIdentity' => array(
                                'identity:type' => 'DNI',
                                'identity:jurisdictionCountry' => 'ESP',
                                'identity:issuer' => 'issuer',
                                'identity:id' => 'id',
                                'identity:certificate' => 'certificate',
                            ),
                            'identity:binarycontentrules' => array(
                                'identity:binarycontentrule binary-content-group-id="1" binarycontentrule-id="1"' => array(
                                    "request_meta:signMethods" => array(
                                        "request_meta:signMethod" => "SMS_VOICE",
                                    )
                                )
                            )
                        )
                    ),
                    'process_meta:subject' => 'subject',
                    'process_meta:body' => 'body',
                    'process_meta:url' => 'LOGALTY_DIRECT_ACCESS_DOC_IN_FRAME',
                    'process_meta:email' => 'sender@example.com',
                    'process_meta:userdefined name="name"' => 'value',
                );

i have a functions in my class, that to create my xml file, i´m sending or $logalty_data_header or $logalty_data_process

in my class i have:

public function array_to_xml($data_header, $data_process, $path = null, $rootElement = null, $xml = null)
        {
            $_xml = $xml;
     
            // If there is no Root Element then insert root
            if ($_xml === null) {
                $xml = new \SimpleXMLElement($rootElement !== null ? $rootElement : '<pt:request xmlns:pt="urn:logalty:schemas:core:1.0" xmlns:identity="urn:logalty:schemas:core:identity:1.0" xmlns:process_meta="urn:logalty:schemas:process:meta:1.0" xmlns:ptforms="urn:logalty:schemas:forms:1.0" xmlns:request_meta="urn:logalty:schemas:request:meta:1.0"></pt:request>');
            }

            $wrapper = $xml->addChild('pt:request_meta');
            
            // Visit all key value pair
            foreach ($data_header as $k => $v) {
                // If there is nested array then
                if (is_array($v)) { 
                    // Call function for nested array
                    $this->array_to_xml($v, $k, $wrapper->addChild($k));
                }else {
                    // Simply add child element.
                    $wrapper->addChild($k, $v);
                }
            }

            $wrapper2 = $xml->addChild('pt:process_meta');
            $this->processData($data_process, $xml, $wrapper2);

            
            
            return $xml->asXML($path.'/installation.xml');
        }

and in my function processData i have a:

private function processData($data_process, $xml, $wrapper2)
        {
            foreach ($data_process as $k => $v) {
                // If there is nested array then
                if (is_array($v)) { 
                    // Call function for nested array
                    $this->processData($v, $k, $wrapper2->addChild($k));
                }else {
                    // Simply add child element.
                    $wrapper2->addChild($k, $v);
                }
            }
        }

i think that my wrong it´s in array_to_xml but i don´t know where are my error. This xml, it´s for send it to API and need create with first format.

Thanks for readme and sorry for my bad english


Solution

  • Try this

    
    $logalty_data_header = [
        'request_meta:service' => 'instalacion_id_' . $id,
        'request_meta:time2close unit="d" value="28"' => "",
        'request_meta:time2save unit="d" value="1825"' => "",
        'request_meta:lopd' => 0,
        'request_meta:retryprotocol' => 3,
        'request_meta:synchronous' => false,
        'request_meta:tsa' => 0,
        'request_meta:userdefined name="php"' => '8.1.6',
    ];
    
    $logalty_data_process = array(
        'process_meta:generator' => 'generator',
        'process_meta:language' => 'es-ES',
        'process_meta:receivers' => array(
            'identity:receiver receiver-id="1"' => array(
                'identity:personalData' => array(
                    'identity:firstname' => 'first',
                    'identity:middlename' => 'middle',
                    'identity:lastname1' => 'last1',
                    'identity:lastname2' => 'last2',
                ),
                // ... other nested data
            )
        ),
        // ... other process data
    );
    
    // Create a new XML document
    $xml = new DOMDocument('1.0', 'utf-8');
    $xml->formatOutput = true;  // Enable formatting for readability
    
    // Create the root element with namespaces
    $root = $xml->createElementNS('urn:logalty:schemas:core:1.0', 'pt:request');
    $root->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:identity', 'urn:logalty:schemas:core:identity:1.0');
    $root->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:process_meta', 'urn:logalty:schemas:process:meta:1.0');
    $root->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:ptforms', 'urn:logalty:schemas:forms:1.0');
    $root->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:request_meta', 'urn:logalty:schemas:request:meta:1.0');
    $xml->appendChild($root);
    
    // Create request_meta element and its children
    $requestMeta = $xml->createElement('request_meta');
    $root->appendChild($requestMeta);
    createXmlChildren($xml, $requestMeta, $logalty_data_header);
    
    // Create process_meta element and its children
    $processMeta = $xml->createElement('process_meta');
    $root->appendChild($processMeta);
    createXmlChildren($xml, $processMeta, $logalty_data_process);
    
    // Function to create nested XML elements recursively
    function createXmlChildren($xml, $parent, $data) {
        foreach ($data as $key => $value) {
            $parts = explode(':', $key);
            $tagName = $parts[count($parts) - 1];
            $element = $xml->createElement($tagName);
            $parent->appendChild($element);
    
            if (is_array($value)) {
                createXmlChildren($xml, $element, $value);
            } else {
                $element->textContent = $value;
            }
    
            // Handle attributes if present
            if (count($parts) > 1) {
                $attributes = array_slice($parts, 0, -1);
                foreach ($attributes as $attribute) {
                    $name = explode('=', $attribute)[0];
                    $value = explode('=', $attribute)[1];
                    $element->setAttribute($name, $value);
                }
            }
        }
    }
    
    // Save the XML to a file or output it
    $xml->save('output.xml');  // Save to a file
    // echo $xml->saveXML();  //