我有一个包含一些XML值的字段$xml
。首先,我必须提到元素不是分别在新行(行)中分隔,而是像没有新行的字符串一样绑定在一起。
我将首先显示XML结构,使其看起来容易“可读”。
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv=" http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<p:queryBillingAccountResponse xmlns:p=" http://www.ibm.com">
<ns0:customerAccount xmlns:ns0=" http://www.ibm.com/xmlns/">
<AccountStatus>Paid</AccountStatus>
<ComponentCustomerAccount>
<Name>ADSL 4</Name>
<CharacteristicValue>
<Characteristic>
<Name>Balance</Name>
</Characteristic>
<Value>0.0</Value>
</CharacteristicValue>
<AccountStatus>Paid</AccountStatus>
</ComponentCustomerAccount>
</ns0:customerAccount>
</p:queryBillingAccountResponse>
</soapenv:Body>
</soapenv:Envelope>
<AccountStatus>Paid</AccountStatus>
</ComponentCustomerAccount>
</ns0:customerAccount>
</p:queryBillingAccountResponse>
</soapenv:Body>
</soapenv:Envelope>
但我必须再次提到$ xml字段中的实际值并不那么容易阅读。 例如,它看起来像这样
<?xml version="1.0" encoding="utf-8"?><soapenv:Envelope xmlns:soapenv=" http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><p:queryBillingAccountResponse xmlns:p=" http://www.ibm.com">.......
我想删除元素:?xmlversion
soapenv:Envelope
和soapenv:Body
及其属性。我想在xml值的开始和结束时删除它们。其他所有东西都保持原样1如何实现这个目标?所以我在php字段中的新值应该从queryBillingAccountResponse
元素开始。谢谢
答案 0 :(得分:2)
对于有效的XML,您可以使用SimpeXML
或DOMDocument
来查询body元素的子节点。
$xml = '<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<p:queryBillingAccountResponse xmlns:p="http://www.ibm.com">
<ns0:customerAccount xmlns:ns0="http://www.ibm.com/xmlns/">
<AccountStatus>Paid</AccountStatus>
<ComponentCustomerAccount>
<Name>ADSL 4</Name>
<CharacteristicValue>
<Characteristic>
<Name>Balance</Name>
</Characteristic>
<Value>0.0</Value>
</CharacteristicValue>
<AccountStatus>Paid</AccountStatus>
</ComponentCustomerAccount>
</ns0:customerAccount>
</p:queryBillingAccountResponse>
</soapenv:Body>
</soapenv:Envelope>';
$xml = simplexml_load_string($xml);
$xml = $xml->xpath('//soapenv:Body/child::*')[0];
echo $xml->asXML();
结果是:
<p:queryBillingAccountResponse xmlns:p="http://www.ibm.com">
<ns0:customerAccount xmlns:ns0="http://www.ibm.com/xmlns/">
<AccountStatus>Paid</AccountStatus>
<ComponentCustomerAccount>
<Name>ADSL 4</Name>
<CharacteristicValue>
<Characteristic>
<Name>Balance</Name>
</Characteristic>
<Value>0.0</Value>
</CharacteristicValue>
<AccountStatus>Paid</AccountStatus>
</ComponentCustomerAccount>
</ns0:customerAccount>
</p:queryBillingAccountResponse>
但问题是您的XML无效,我不知道它是否是复制和粘贴错误。
答案 1 :(得分:1)
这是最简单的,也是XSLT最简单的方法:
function extract_body_stripns($xmlstring) {
static $xsl = NULL;
if ($xsl === NULL) {
$xsl_soap_body_nons = <<<'EOT'
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" method="xml" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[namespace-uri()]" priority="1">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*[namespace-uri()]" priority="1">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="/soapenv:Envelope/soapenv:Body/*"/>
</xsl:template>
</xsl:stylesheet>
EOT;
$style = new DOMDocument();
$style->loadXML($xsl_soap_body_nons, LIBXML_COMPACT | LIBXML_NOBLANKS | LIBXML_NONET);
$xsl = new XSLTProcessor();
$xsl->importStylesheet($style);
unset($style);
}
$d = new DOMDocument();
$d->loadXML($xmlstring, LIBXML_COMPACT | LIBXML_NONET);
$newd = $xsl->transformToDoc($d);
unset($d);
return $newd->saveXML($newd->documentElement);
}
使用此功能:
echo extract_body_stripns($xmlString);
结果是:
<queryBillingAccountResponse>
<customerAccount>
<ComponentCustomerAccount>
<Name>ADSL 4</Name>
<CharacteristicValue>
<Characteristic>
<Name>Balance</Name>
</Characteristic>
<Value>0.0</Value>
</CharacteristicValue>
<AccountStatus>Paid</AccountStatus>
</ComponentCustomerAccount>
</customerAccount>
</queryBillingAccountResponse>
请注意,如果源文档中有命名空间属性,则删除命名空间的过程可能会导致丢失其中一些属性。例如。使用元素<myelement ns:myattrib="a" myattrib="b"/>
,您的一个属性将会丢失,哪一个您将失去的属性不一致!
答案 2 :(得分:-1)
您可以使用ereg_replace http://php.net/manual/en/function.ereg-replace.php
使用正则表达式识别要删除的元素。