XML解析不一致

时间:2016-12-13 18:47:56

标签: php xml xml-parsing simplexml

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

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

这个问题是它将多个子节点视为一个索引数组,每个子节点包含一个关联数组,但如果它只是父标记中的一个子节点,它就不会创建一个索引数组使用一个元素并将一个assoc数组直接放到父标记元素。我需要这些场景的输出是一致的。即索引数组首先不依赖于子项的数量。我的目标是解析后的一致模式。

多个孩子的一个例子:

输入:

    <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, ...]]]

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

2 个答案:

答案 0 :(得分:1)

我最终使用了saber / 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->serviceSabre\Xml\Service,$ assocParser和$ indexParser使用$makeArray闭包从lib的标准输出创建我需要的数组结构。

答案 1 :(得分:0)

实际上解析非常一致 - 但转换是有限的,因为JSON没有与XML相同的格式功能。

您的请求无法正常工作,因为通用转换器无法知道此处是否“可能”是多个子节点(具有相同名称)。如果它无论如何都会创建数组,它会对任何元素执行此操作(甚至像foo(int&)这样的父节点)。像JsonML这样的一些基于JSON的格式实际上就是这样。

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

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

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

如果您需要特定的JSON输出,请使用您自己的逻辑生成它。通过这种方式,您可以确保结构是您需要的结构。