任何重复的XML数组键的解决方法?

时间:2018-11-27 18:37:05

标签: php arrays xml

我知道数组中的重复键是不可能的。我有一个API,可以将数据以XML格式发送到。麻烦的是,在将其转换为XML并将其发送到API之前,我需要将其保存在Array中。该API仅接受我在下面显示的格式。所以这是我的问题,我需要以下方面的帮助:

需要XML格式的API(首选结果):

<root>
  <id>FACE</id>
  <title>FACEBOOK NOVEMBER 2019</title>
  <agreement_id>REDP</agreement_id>
  <contact>Sidra</contact>
  <order_id>4715</order_id>
  <plan_no>417</plan_no>
  <insertion>
      <insertion_date>2019-10-08</insertion_date>
      <start_date>2019-10-08</start_date>
      <end_date>2019-10-09</end_date>
      <PO_number>150</PO_number>
      <price_row>
        <price_code>000</price_code>
        <gross>11111</gross>
      </price_row>
  </insertion>
  <insertion>
      <insertion_date>2019-10-09</insertion_date>
      <start_date>2019-10-09</start_date>
      <end_date>2019-10-10</end_date>
      <PO_number>152</PO_number>
      <price_row>
        <price_code>000</price_code>
        <gross>11111</gross>
      </price_row>
  </insertion>
  <type>method_name</type>
  <password>*******</password>
  <company_id>*******</company_id>
</root>

这对于拥有Array时找不到解决方案,因为insertion块需要像这样完全相同。

这是我将多维数组转换为XML格式的解决方案:

static function addXMLData(\SimpleXMLElement $xml, array $data) {
    array_walk($data, function ($value, $key) use ($xml) {
        if (is_array($value)) {
            $child = $xml->addChild($key);
            self::addXMLData($child, $value);
        } else {
            $xml->addChild($key, $value);
        }
    });
}

static function createXML($data, $root = null) {
    $xml = new \SimpleXMLElement($root ? '<' . $root . '/>' : '<root/>');
    self::addXMLData($xml, $data);
    $dom = dom_import_simplexml($xml)->ownerDocument;
    $dom->encoding = "UTF-8";
    $dom->formatOutput = true;
    echo $dom->saveXML();
}

这是我从客户端发送的阵列:

$order_data = array([
    "id" => 'FACE',
    "title" => 'FACEBOOK NOVEMBER 2019',
    "agreement_id" => 'REDP',
    "contact" => "Sidra",
    "order_id" => 4715,  
    "plan_no" => 417,  
    "insertion" => [       
        "insertion_date" => '2019-10-08',
        "start_date" => '2019-10-08',
        "end_date" => "2019-10-09",
        "PO_number" => 150,
        "price_row" => [
            "price_code" => '000',
            "gross" => 11111
        ],
    ],
    "insertion" => [
            "insertion_date" => '2019-10-09',
            "start_date" => '2019-10-09',
            "end_date" => "2019-10-10",
            "PO_number" => 151,
            "price_row" => [
                "price_code" => '000',
                "gross" => 11111
            ],
        ]
]);
 echo "<pre>";
 print_r($order_data);
 die;

此结果将删除重复的数组键,它将不起作用。我该如何智能地将其转换为XML并保留重复的密钥?

这是我的完整功能,对不起,很多代码。 $data_flatten是上面的数组。 _request内部具有CreateXML方法。我已经硬编码了insertion“批量”

public function create_order_direct($order_data) {

    $data_flatten = [];
    array_walk_recursive($order_data, function ($v, $k) use (&$data_flatten) {
        $data_flatten[$k] = $v;
    });
    // If present = replace
    // Else create new order with entries(insertion)
    if (!isset($data_flatten['order_id'])) {
        $data_flatten['order_id'] = "";
    }

    return $this->__request(__FUNCTION__, [
        "id" => $data_flatten['media_id'],
        "title" => $data_flatten['headline'],
        "agreement_id" => self::AGREEMENT_ID,
        "contact" => $data_flatten['client_contact'],
        "order_id" => $data_flatten['order_id'],
        "plan_no" => $data_flatten['plan_number'],
        "insertion" => [
                "insertion_date" => '2019-10-08',
                "start_date" => '2019-10-08',
                "end_date" => "2019-10-09",
                "PO_number" => 150,
                "price_row" => [
                    "price_code" => '000',
                    "gross" => 11111
                ]
        ],
        "insertions" => [
        [
            "insertion_date" => '2019-10-09',
            "start_date" => '2019-10-09',
            "end_date" => "2019-10-10",
            "PO_number" => 152,
            "price_row" => [
                "price_code" => '000',
                "gross" => 11111
            ],
    ]
    ]);
}









编辑/更新:

谢谢你们。我按照您的建议,现在按照您的建议在insertion块的数组中添加了数组。我现在得到的结果是这样的:

<root>
  <id>FACE</id>
  <title>FACEBOOK NOVEMBER 2019</title>
  <agreement_id>REDP</agreement_id>
  <contact>Sidra</contact>
  <order_id>4715</order_id>
  <plan_no>417</plan_number>
  <insertion>
    <0>
      <insertion_date>2019-10-08</insertion_date>
      <start_date>2019-10-08</start_date>
      <end_date>2019-10-09</end_date>
      <PO_number>150</PO_number>
      <price_row>
        <price_code>000</price_code>
        <gross>11111</gross>
      </price_row>
    </0>
    <1>
      <insertion_date>2019-10-09</insertion_date>
      <start_date>2019-10-09</start_date>
      <end_date>2019-10-10</end_date>
      <PO_number>151</PO_number>
      <price_row>
        <price_code>000</price_code>
        <gross>11111</gross>
      </price_row>
    </1>
  </insertion>
  <type>method_name</type>
  <password>********</password>
</marathon>
我现在看到的唯一的问题是XML为多维数组添加数字。而且我需要在数字键开始的地方包装多个<insertion>块。我该怎么办?

这就是我想要的:

<root>
  <id>FACE</id>
  <title>FACEBOOK NOVEMBER 2019</title>
  <agreement_id>REDP</agreement_id>
  <contact>Sidra</contact>
  <order_id>4715</order_id>
  <plan_no>417</plan_number>
  <insertion>
      <insertion_date>2019-10-08</insertion_date>
      <start_date>2019-10-08</start_date>
      <end_date>2019-10-09</end_date>
      <PO_number>150</PO_number>
      <price_row>
        <price_code>000</price_code>
        <gross>11111</gross>
      </price_row>
  </insertion>
  <insertion>
      <insertion_date>2019-10-09</insertion_date>
      <start_date>2019-10-09</start_date>
      <end_date>2019-10-10</end_date>
      <PO_number>151</PO_number>
      <price_row>
        <price_code>000</price_code>
        <gross>11111</gross>
      </price_row>
  </insertion>
  <type>method_name</type>
  <password>********</password>
</marathon>

1 个答案:

答案 0 :(得分:0)

您需要使用略有不同的结构来避免重复的键:

所以代替:

<key />
<key />

您将使用:

<keys>
  <key />
  <key />
</keys>

http://lists.xml.org/archives/xml-dev/201504/msg00019.html

此时,如果您的转换函数没有自动将其解析为数组,则可以通过为每个新数字键赋予一个数字键而不是一个关联键来进行手动设置。

因此,如果dom子数量> 1,则循环并设置密钥= i + 1