PHP/SOAP - 删除所有命名空间,但首先

PHP/SOAP - Remove all namespaces BUT first

我正在从 PHP 中的数组生成 XML

网络服务提供给我的请求示例如下:

<?xml version="1.0" encoding="UTF-8"?>
<sof:Contract xmlns:s="http://www.fines.pl/simple" xmlns:sof="http://www.fines.pl/sof" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.fines.pl/sof model.xsd ">
    <product>
        <prefix>MOP</prefix>
    </product>
    <participants>
        <customers>
            <main_borrower>
                <personal_data>
                    <pesel></pesel>
                    <firstname></firstname>
                    <lastname></lastname>
                    <firstname_father></firstname_father>
                    <firstname_mother></firstname_mother>
                    <secondname />
                    <sex>female</sex>
                </personal_data>
                <contact_data>
                    <addresses>
                        <address>
                            <type>registered</type>
                            <street_name></street_name>
                            <block_number></block_number>
                            <flat_number></flat_number>
                            <postal_code></postal_code>
                            <city></city>
                        </address>
                    </addresses>
                    <phones_mobile>
                        <phone_mobile>
                            <type>personal</type>
                            <number>602200300</number>
                        </phone_mobile>
                    </phones_mobile>
                </contact_data>
                <incomes>
                    <income>
                        <type>employment</type>
                        <main_income>true</main_income>
                        <fixed_term_contract>false</fixed_term_contract>
                        <paychecks>
                            <paycheck>
                                <amount_net>
                                    <amount>1444.00</amount>
                                    <currency>PLN</currency>
                                </amount_net>
                                <type>base</type>
                            </paycheck>
                        </paychecks>
                    </income>
                </incomes>
                <household_pointer>/households.0</household_pointer>
            </main_borrower>
        </customers>
    </participants>
</sof:Contract>

我实际得到的是这个命名空间 sof: 前缀出现在每个元素中(<sof:product><sof:participants> 等)

因此 Scheme 验证器失败。我怎样才能摆脱那些额外的 sof: 前缀?

我的PHP是:

<?php
$contract = array(
        'product' => array(
            'prefix' => 'MOP',
        ),
        'participants' => array(
            'customers' => array(
                'main_borrower' => array(
                    'personal_data' => array(
                        'pesel' => $pesel,
                        'firstname' => $firstname,
                        'lastname' => $lastname,
                        'sex' => $xmlsex,
                    ),
                    'contact_data' => array(
                        'addresses' => array(
                            'address' => array(
                                'type' => 'registered',
                                'street_name' => $city,
                                'block_number' => '1',
                                'flat_number' => '1',
                                'postal_code' => $postcode,
                                'city' => $city,
                            ),
                        ),
                        'phones_mobile' => array(
                            'phone_mobile' => array(
                                'type' => 'personal',
                                'number' => $phone,
                            ),
                        ),
                    ),
                    'incomes' => array(
                        'income' => array(
                            'type' => 'employment',
                            'main_income' => 'true',
                            'fixed_term_contract' => 'false',
                            'paychecks' => array(
                                'paycheck' => array(
                                    'amount_net' => array(
                                        'amount' => $price,
                                        'currency' => 'PLN',
                                    ),
                                    'type' => 'base',
                                ),
                            ),
                        ),
                    ),
                ),
            ),
        ),
    );
function array_to_xml($array, &$xml) {
    foreach($array as $key => $value) {
        if(is_array($value)) {
            if(!is_numeric($key)){
                $subnode = $xml->addChild("$key");
                array_to_xml($value, $subnode);
            } else {
                array_to_xml($value, $xml);
            }
        } else {
            $xml->addChild("$key","$value");
        }
    }
};
$xml = new SimpleXMLElement("<?xml version=\"1.0\" encoding=\"UTF-8\"?><sof:Contract xmlns:s=\"http://www.fines.pl/simple\" xmlns:sof=\"http://www.fines.pl/sof\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.fines.pl/sof model.xsd \"></sof:Contract>");

array_to_xml($contract, $xml);

$xml->asXML('contract.xml');
?>

我通过向 addChild 提供第三个参数来删除名称空间,自己设法解决了这个问题,如下所示:

function array_to_xml($array, &$xml) {
    foreach($array as $key => $value) {
        if(is_array($value)) {
            if(!is_numeric($key)){
                $subnode = $xml->addChild("$key",'','');
                array_to_xml($value, $subnode);
            } else {
                array_to_xml($value, $xml);
            }
        } else {
            $xml->addChild("$key","$value",'');
        }
    }
};

考虑 XSLT, the special-purpose language designed to transform XML files and manipulating namespaces are among its regular uses. PHP can run XSLT 1.0 scripts using its php-xsl class。使用这种方法,不需要 array 构建、foreach 循环、if 逻辑或递归 function

XSLT (另存为.xsl文件,特殊的.xml文件)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <!-- IDENTITY TRANSFROM: COPY DOC AS IS -->
  <xsl:template match="@*|node()">
    <xsl:copy>    
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- REMOVE NAMESPACE PREFIXES -->
  <xsl:template match="*[local-name()!='Contract']">
    <xsl:element name="{local-name()}">   
      <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

输入 XML (假设下面复制OP的return)

<?xml version="1.0" encoding="UTF-8"?>
<sof:Contract xmlns:s="http://www.fines.pl/simple" xmlns:sof="http://www.fines.pl/sof" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.fines.pl/sof model.xsd ">
    <sof:product>
        <sof:prefix>MOP</sof:prefix>
    </sof:product>
    <sof:participants>
        <sof:customers>
            <sof:main_borrower>
                <sof:personal_data>
                    <sof:pesel></sof:pesel>
                    <sof:firstname></sof:firstname>
                    <sof:lastname></sof:lastname>
                    <sof:firstname_father></sof:firstname_father>
                    <sof:firstname_mother></sof:firstname_mother>
                    <sof:secondname />
                    <sof:sex>female</sof:sex>
                </sof:personal_data>
                <sof:contact_data>
                    <sof:addresses>
                        <sof:address>
                            <sof:type>registered</sof:type>
                            <sof:street_name></sof:street_name>
                            <sof:block_number></sof:block_number>
                            <sof:flat_number></sof:flat_number>
                            <sof:postal_code></sof:postal_code>
                            <sof:city></sof:city>
                        </sof:address>
                    </sof:addresses>
                    <sof:phones_mobile>
                        <sof:phone_mobile>
                            <sof:type>personal</sof:type>
                            <sof:number>602200300</sof:number>
                        </sof:phone_mobile>
                    </sof:phones_mobile>
                </sof:contact_data>
                <sof:incomes>
                    <sof:income>
                        <sof:type>employment</sof:type>
                        <sof:main_income>true</sof:main_income>
                        <sof:fixed_term_contract>false</sof:fixed_term_contract>
                        <sof:paychecks>
                            <sof:paycheck>
                                <sof:amount_net>
                                    <sof:amount>1444.00</sof:amount>
                                    <sof:currency>PLN</sof:currency>
                                </sof:amount_net>
                                <sof:type>base</sof:type>
                            </sof:paycheck>
                        </sof:paychecks>
                    </sof:income>
                </sof:incomes>
                <sof:household_pointer>/households.0</sof:household_pointer>
            </sof:main_borrower>
        </sof:customers>
    </sof:participants>
</sof:Contract>

PHP

// LOAD XML AND XSLT 
$doc = new DOMDocument();    
$doc->load('Input.xml');

$xsl = new DOMDocument;
$xsl->load('XSLTScript.xsl');

// CONFIGURE TRANSFORMER
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl); 

// RUN TRANSFORMATION
$newXML = $proc->transformToXML($doc);

// ECHO TO CONSOLE
echo $newXML;

// SAVE OUTPUT TO FILE
file_put_contents('Output.xml', $newXML);

输出 XML (除根以外的所有前缀都已删除)

<?xml version="1.0" encoding="utf-8"?>
<sof:Contract xsi:schemaLocation="http://www.fines.pl/sof model.xsd " xmlns:sof="http://www.fines.pl/sof" xmlns:s="http://www.fines.pl/simple" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <product>
    <prefix>MOP</prefix>
  </product>
  <participants>
    <customers>
      <main_borrower>
        <personal_data>
          <pesel />
          <firstname />
          <lastname />
          <firstname_father />
          <firstname_mother />
          <secondname />
          <sex>female</sex>
        </personal_data>
        <contact_data>
          <addresses>
            <address>
              <type>registered</type>
              <street_name />
              <block_number />
              <flat_number />
              <postal_code />
              <city />
            </address>
          </addresses>
          <phones_mobile>
            <phone_mobile>
              <type>personal</type>
              <number>602200300</number>
            </phone_mobile>
          </phones_mobile>
        </contact_data>
        <incomes>
          <income>
            <type>employment</type>
            <main_income>true</main_income>
            <fixed_term_contract>false</fixed_term_contract>
            <paychecks>
              <paycheck>
                <amount_net>
                  <amount>1444.00</amount>
                  <currency>PLN</currency>
                </amount_net>
                <type>base</type>
              </paycheck>
            </paychecks>
          </income>
        </incomes>
        <household_pointer>/households.0</household_pointer>
      </main_borrower>
    </customers>
  </participants>
</sof:Contract>