【问题标题】:Inconsistent XML parsing不一致的 XML 解析
【发布时间】:2016-12-13 18:47:56
【问题描述】:

我需要使用一些非常简单快捷的解决方案将 XML 文件转换为数组。这个对我来说很好看:

 json_decode(json_encode(simplexml_load_string($xmlContent, "SimpleXMLElement", LIBXML_NOCDATA)), true);

这样做的问题是,它将多个子元素视为一个索引数组,每个子元素由一个关联数组组成,但如果父标记中只有一个子元素,它不会创建一个包含一个元素的索引数组并放置一个将数组直接关联到父标记元素。我需要这些场景的输出保持一致。 IE。索引数组首先不取决于孩子的数量。我的目标是解析后的一致模式。

多个孩子的例子:

输入:

    <PICK_NOTE_LINES>
          <LINE>
            <PICK_LINE_NUM>1</PICK_LINE_NUM>
            <PRODUCT_CODE>3342</PRODUCT_CODE>
            <BATCH_CODE></BATCH_CODE>
            <QUANTITY>1</QUANTITY>
          </LINE>
          <LINE>
            <PICK_LINE_NUM>2</PICK_LINE_NUM>
            <PRODUCT_CODE>5285</PRODUCT_CODE>
            <BATCH_CODE></BATCH_CODE>
            <QUANTITY>1</QUANTITY>
          </LINE>
</PICK_NOTE_LINES>

输出(LINE 父元素中的索引数组):

['PICK_NOTE_LINES'=>['LINE'=>[['PICK_LINE_NUM'=>1, ...],['PICK_LINE_NUM'=>2, ...]]]

一个孩子的例子:

<PICK_NOTE_LINES>
      <LINE>
        <PICK_LINE_NUM>1</PICK_LINE_NUM>
        <PRODUCT_CODE>3342</PRODUCT_CODE>
        <BATCH_CODE></BATCH_CODE>
        <QUANTITY>1</QUANTITY>
      </LINE>
    </PICK_NOTE_LINES>

输出(行父元素中的关联数组):

['PICK_NOTE_LINES'=> ['LINE'=>['PICK_LINE_NUM'=>1, ...]]]

是否有可能让它总是将孩子放入索引数组中,即使它只有一个孩子?如果不可能,我可以使用什么来获得一致的输出?

【问题讨论】:

  • 显然,您当前的代码不可能。修改它来做你需要的事情
  • @u_mulder 我想也许有一些解析器选项可以做到这一点。

标签: php xml xml-parsing simplexml


【解决方案1】:

我最终使用了 sabre/xml 库。几行代码,它给了我我需要的结构:

$this->service->elementMap = [
            '{}DOCUMENT' => $assocParser,
            '{}DATA' => $assocParser,
            '{}CONSIGNMENTS' => $indexParser,
            '{}PICK_NOTE_LINES' => function ($reader) use ($makeArray) {
                $lines = [];
                $children = $reader->parseInnerTree();
                foreach ($children as $child) {
                    $lines[] = $makeArray($child['value']);
                }
                return $lines;
            },
        ];

其中$this-&gt;serviceSabre\Xml\Service,$assocParser 和$indexParser 使用$makeArray 闭包从lib 的标准输出创建我需要的数组结构。

【讨论】:

    【解决方案2】:

    实际上解析是相当一致的——但是转换是有限的,因为 JSON 没有与 XML 相同的格式特性。

    您的请求无法工作,因为通用转换器无法知道此处是否“可能”是多个孩子(同名)。如果它无论如何都会创建数组,它会为任何元素(甚至像PICK_NOTE_LINES这样的父节点)执行此操作。一些基于 JSON 的格式(如 JsonML)实际上会做类似的事情。

    SimpleXML 本身允许您将每个元素视为单个节点或列表。您知道如何访问数据,从而避免问题。

    如果您想创建特定的 JSON 输出,则需要编写自己的转换逻辑、读取 XML 并创建对象/数组结构。

    我强烈建议避免泛型转换。如果您正在阅读 XML,请保留 SimpleXMLElement,转换意味着您将失去数据和 API 功能。

    如果您需要特定的 JSON 输出,请使用您自己的逻辑生成它。这样您就可以确定该结构是您需要的结构。

    【讨论】:

      猜你喜欢
      • 2014-10-11
      • 1970-01-01
      • 1970-01-01
      • 2013-02-25
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 2018-12-26
      相关资源
      最近更新 更多