2017-12-11 5 views
0

PHPでXMLノードの値を変更する際に、いくつかの問題があります。PHP XMLノードの値を変更する

私のXMLは、次の

<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
     xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
     <soap:Body> 
      <ProcessTransaction 
        xmlns="http://example.com"> 
        <TransactionRequest 
         xmlns="http://example.com"> 
         <Header> 
           <RequestType>SALE</RequestType> 
           <RequestMethod>SYNCHRONOUS</RequestMethod> 
           <MerchantInfo> 
            <PosName>kwstasna</PosName> 
            <PosID>1234</PosID> 
           </MerchantInfo> 
         </Header> 
        </TransactionRequest> 
      </ProcessTransaction> 
     </soap:Body> 
</soap:Envelope> 

であると私はPosNamePosIDを変更したいです。 XMLはPOST要求から受信されます。 もし私がprint_r($REQUEST['xml'] の場合は、テキストの値を取得します。

そして、私が試したことは

$posid = '321'; 
$posname = 'nakwsta'; 

$result = $xml->xpath("/soap:Envelope/soap:Body/ProcessTransaction/TransactionRequest/Header/MerchantInfo"); 

$result[0]->PosID = $posid; 
$result[0]->PosName = $posname; 

echo $result; 

以下ですが、私は空の配列Array[]

を取得し、私は私のミスは、例えば<soap:Envelopeの値であると思います。 同じ問題を抱え、それを解決する方法を見つけた人は誰ですか?

ありがとうございます。

+0

正しいパス(http://php.net/manual/en/simplexmlelement.registerxpathnamespace)を得るには、名前空間を$ xmlに登録する必要があります。php) – Edwin

+0

@Edwin存在する最初の部分3つの名前空間何をすべきですか? –

+0

これはあなたが使用しようとしているノードであるため、 'xmlns =" http://example.com "'を登録する必要があります(マニュアルの最初の例を参照)。 – Edwin

答えて

4

ProcessTransaction要素(およびすべての子ノード)は、"http://example.com"名前空間にあります。あなたがxpath()を使用してそれらにアクセスする場合は、名前空間接頭辞を登録する必要があります:

$xml->registerXPathNamespace('ex', 'http://example.com'); 

次に、あなたのクエリ

$result = $xml->xpath("/soap:Envelope/soap:Body/ex:ProcessTransaction/ex:TransactionRequest/ex:Header/ex:MerchantInfo"); 

のすべての関連する部分での残りの部分をex接頭辞を使用することができますhttps://eval.in/916856

+0

あなたの例は正しいですが、xmlに変換する方法はありますか? –

+0

あなたは '$ xml-> asXML()'を呼び出すことができます。新しい例で更新します – iainn

+0

https://eval.in/916861 – iainn

2

PHPがsetParameter()で下位のスクリプトに値を渡すパラメータ化されたXSLT(パラメータ化されたSQLと異なります)を考えてみましょう。

情報として、XSLT(兄弟からXPath)は、XMLファイルを変換するための特別な目的の言語です。 PHPはXSLクラスのXSLT 1.0スクリプトを実行できます。具体的には、Identity Transformを実行してXMLをそのままコピーした後、PosNamePosIDノードを書き換えます。デフォルトの名前空間は、の文書にアラインされたトップルートタグに応じて処理されます。

XSLT(としての.xslファイル、特別な整形式の.xmlファイルを保存)

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

    <xsl:param name="PosNameParam"/> 
    <xsl:param name="PosIDParam"/> 

    <!-- IDENTITY TRANSFORM --> 
    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <!-- RE-WRITE PosName NODE --> 
    <xsl:template match="doc:PosName">  
    <xsl:copy> 
     <xsl:value-of select="$PosNameParam"/> 
    </xsl:copy> 
    </xsl:template> 

    <!-- RE-WRITE PosID NODE --> 
    <xsl:template match="doc:PosID"> 
    <xsl:copy> 
     <xsl:value-of select="$PosIDParam"/> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

PHP

$posid = '321'; 
$posname = 'nakwsta'; 

// Load XML and XSL 
$xml = new DOMDocument; 
$xml->load('Input.xml'); 

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

// Configure transformer 
$proc = new XSLTProcessor; 
$proc->importStyleSheet($xsl); 

// Assign values to XSLT parameters 
$proc->setParameter('', 'PosNameParam', $posid); 
$proc->setParameter('', 'PosIDParam', $posname); 

// Transform XML source 
$newXML = new DOMDocument; 
$newXML = $proc->transformToXML($xml); 

// Output to console 
echo $newXML; 

// Output to file 
file_put_contents('Output.xml', $newXML); 

出力

<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
     <soap:Body> 
      <ProcessTransaction xmlns="http://example.com"> 
        <TransactionRequest> 
         <Header> 
           <RequestType>SALE</RequestType> 
           <RequestMethod>SYNCHRONOUS</RequestMethod> 
           <MerchantInfo> 
            <PosName>nakwsta</PosName> 
            <PosID>321</PosID> 
           </MerchantInfo> 
         </Header> 
        </TransactionRequest> 
      </ProcessTransaction> 
     </soap:Body> 
</soap:Envelope> 
+0

これは素晴らしく見えますが、このような利点は何ですか? (ありがとう) – Edwin

+1

今は少し変更を加えているので、残念です。しかし、新しいノードのような実質的な変換を行い、子供を平らにしてcsv/txtに変換する必要がある場合、XSLTは多くの 'foreach'ループと' if'ロジックを避けるための素晴らしいツールです。また、私は最近、PHPとPythonでパラメータを渡すことについても知っていました。あなたの質問で楽しく過ごしたいと思っていました。 – Parfait

関連する問題