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>
我正在从 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>