【问题标题】:Adding child node to XML variable - PHP将子节点添加到 XML 变量 - PHP
【发布时间】:2018-06-01 12:03:00
【问题描述】:

我正在尝试填充需要使用 php curl 发送的 SOAP 请求的值。我已经使用soap.xml 请求设置了一个变量,并获得了所有需要传递的数据。

$shipBody = '<?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:v1="http://servicescom/ws/merchantAPI/v1.0">
      <soap:Header>
        <wsse:Security xmlns:wsse="http://docs.oasis-1.xsd">
          <wsse:UsernameToken>
            <wsse:Username>'.$username.'</wsse:Username>
            <wsse:Password>'.$password.'</wsse:Password>
          </wsse:UsernameToken>
        </wsse:Security>
      </soap:Header>
      <soap:Body>
        <v1:parcelShipmentNotification>
          <parcel>
            <carrierName>'.$carrierName.'</carrierName>
            <carrierService>'.$carrierService.'</carrierService>
            '.$xml_data->children('itemdatastring')->asXML().'<!--Tried adding data as children but didn't return anything-->
            '.$xml_data->asXML().'<!--This worked but i couldn't remove the extra "itemdatastring"-->
            <orderId>'.$exId.'</orderId>
            <parcelId>'.$parcelId.'</parcelId>
            <parcelReference>'.$shipDate.'</parcelReference>
            <shippingDate>'.$shipDate.'</shippingDate>
            <trackingURL>https://tools.usps.com/go/TrackConfirmAction?tLabels='.$trackingUrl.'</trackingURL>
          </parcel>
          <requestPackingSlip>true</requestPackingSlip>
        </v1:parcelShipmentNotification>
      </soap:Body>
    </soap:Envelope>';

我能够创建一个函数来获取所有带有 sku 和 qty 的行项目,但是我在将返回值传递给 $shipBody 变量时遇到了困难。这是一个示例订单项;

$myShipment = array ( 
array(
    'sku' => 'BA2222222',
    'qty' => '2'
    ),
array(
    'sku' => 'BA111111',
    'qty' => '4'
    ),
);

这是我目前获取订单项 XML 的方式。

function array_to_xml( $dataToConvert, $xml_data ) {
    foreach( $dataToConvert as $key => $value ) {
        if( is_numeric($key) ){
            $key = 'items'; //dealing with <0/>..<n/> issues
        }
        if( is_array($value) ) {
            $subnode = $xml_data->addChild($key);
            array_to_xml($value, $subnode);
        } else {
            $xml_data->addChild("$key",htmlspecialchars("$value"));
        }
     }
}

$orderLineItems = array();
foreach ($myShipment as $orderItem) {
    $orderItemSku = $orderItem['sku'];
    $orderItemQty = $orderItem['qty'];

    $orderLineItems[] = array(
      'quantity' => $orderItemQty,
      'sku' => $orderItemSku
    );
}

$xml_data = new SimpleXMLElement('<itemdatastring></itemdatastring>');
array_to_xml($orderLineItems,$xml_data);

最后,完成的文件应该是这样的;

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:v1="http://servicescom/ws/merchantAPI/v1.0">
  <soap:Header>
    <wsse:Security xmlns:wsse="http://docs.oasis-1.xsd">
      <wsse:UsernameToken>
        <wsse:Username>'.$username.'</wsse:Username>
        <wsse:Password>'.$password.'</wsse:Password>
      </wsse:UsernameToken>
    </wsse:Security>
  </soap:Header>
  <soap:Body>
    <v1:parcelShipmentNotification>
      <parcel>
        <carrierName>'.$carrierName.'</carrierName>
        <carrierService>'.$carrierService.'</carrierService>
        <items>
            <quantity>2</quantity>
            <sku>BA2222222</sku>
        </items>
        <items>
            <quantity>4</quantity>
            <sku>BA111111</sku>
        </items>
        <orderId>'.$exId.'</orderId>
        <parcelId>'.$parcelId.'</parcelId>
        <parcelReference>'.$shipDate.'</parcelReference>
        <shippingDate>'.$shipDate.'</shippingDate>
        <trackingURL>https://tools.usps.com/go/TrackConfirmAction?tLabels='.$trackingUrl.'</trackingURL>
      </parcel>
      <requestPackingSlip>true</requestPackingSlip>
    </v1:parcelShipmentNotification>
  </soap:Body>
</soap:Envelope>

任何帮助/指针将不胜感激。 谢谢

【问题讨论】:

  • 您能edit 稍微简化一下示例吗?这里有很多额外的 XML,我认为与问题无关 - 尝试将其减少到 minimal reproducible example,即使这意味着使用大量 &lt;foo&gt;&lt;example&gt; 组成您自己的 XML 文档。

标签: php arrays xml simplexml


【解决方案1】:

当您调用-&gt;children() 时,您会返回一个节点列表,因此尝试调用$xml_data-&gt;children('itemdatastring')-&gt;asXML() 将失败。

你可以做类似...

$itemString = '';
foreach ( $xml_data->children() as $item ) {
    $itemString .= $item->asXML();
}

这将从每个单独的元素构建一个字符串,然后在您的 XML 中使用 $itemString

【讨论】:

  • 请注意,您在此处作为'itemdatastring' 传递的参数将被解释为命名空间URI。我认为您在这里真正想要的是名为 &lt;itemdatastring&gt; 的子元素,即 foreach ( $xml_data-&gt;itemdatastring as $item )
  • 复制 OP 的代码并且没有足够清醒来实际阅读它的问题:-/ 已更正 - 谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-25
  • 1970-01-01
  • 2013-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多