0

$xmlXML 値を含むフィールドが 1 つあります。最初に、要素は改行 (行) ごとに区切られていませんが、改行のない文字列のように結合されていることに言及する必要があります。

最初に、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要素から開始する必要があります。ありがとうございました

4

3 に答える 3

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が無効であり、それがコピーアンドペーストエラーであるかどうかわからないことです。

于 2013-03-22T08:05:36.050 に答える
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"/>の場合、属性の 1 つが失われ、どの属性が失われるかは一貫していません!

于 2013-03-23T14:46:15.613 に答える
-1

ereg_replace http://php.net/manual/en/function.ereg-replace.phpを使用できます

正規表現を使用して、削除する要素を特定します。

于 2013-03-22T08:04:00.677 に答える