【问题标题】:Parsing XML file with Laravel使用 Laravel 解析 XML 文件
【发布时间】:2018-09-08 14:09:37
【问题描述】:

好的,所以我很坚持这一点。我有一个看起来有点像这样的半复杂 XML 文件:

<?xml version="1.0" encoding="UTF-8"?>

<community ID="1234" POSTDATE="20180329" xmlns="" COMPANY="SAMPLE CO">
   <data1>
      <datatype ID="0001">
         <utpricing LT="1" STARTDATE="20150102" ENDDATE="20160102" BASEAMOUNT="99" CONCESSION="0.00" EFFAMOUNT="99" CONTYPE="SAMPLE" CONVALUE="0.00"/>
      <utpricing LT="1" STARTDATE="20150102" ENDDATE="20160102" BASEAMOUNT="99" CONCESSION="0.00" EFFAMOUNT="99" CONTYPE="SAMPLE" CONVALUE="0.00"/>
      <utpricing LT="1" STARTDATE="20150102" ENDDATE="20160102" BASEAMOUNT="99" CONCESSION="0.00" EFFAMOUNT="99" CONTYPE="SAMPLE" CONVALUE="0.00"/>
      <utpricing LT="1" STARTDATE="20150102" ENDDATE="20160102" BASEAMOUNT="99" CONCESSION="0.00" EFFAMOUNT="99" CONTYPE="SAMPLE" CONVALUE="0.00"/>
</data1>
          <datatype ID="0002">
             <utpricing LT="2" STARTDATE="20160102" ENDDATE="20170102" BASEAMOUNT="99" CONCESSION="0.00" EFFAMOUNT="99" CONTYPE="SAMPLE" CONVALUE="0.00"/>
          <utpricing LT="1" STARTDATE="20150102" ENDDATE="20160102" BASEAMOUNT="99" CONCESSION="0.00" EFFAMOUNT="99" CONTYPE="SAMPLE" CONVALUE="0.00"/>
          <utpricing LT="1" STARTDATE="20150102" ENDDATE="20160102" BASEAMOUNT="99" CONCESSION="0.00" EFFAMOUNT="99" CONTYPE="SAMPLE" CONVALUE="0.00"/>
          <utpricing LT="1" STARTDATE="20150102" ENDDATE="20160102" BASEAMOUNT="99" CONCESSION="0.00" EFFAMOUNT="99" CONTYPE="SAMPLE" CONVALUE="0.00"/>
    </datatype>
</data1>
  <data2>
      <data2 ID="141" NAME="IAM | 1 | 1.00" SQFTMIN="111" SQFTMAX="222"/>
      <data2 ID="142" NAME="ASA | 1 | 1.00" SQFTMIN="111" SQFTMAX="222"/>
      <data2 ID="143" NAME="MPL | 1 | 1.00" SQFTMIN="111" SQFTMAX="222"/>
      <data2 ID="144" NAME="EBI | 1 | 1.00" SQFTMIN="111" SQFTMAX="222"/>
      <data2 ID="145" NAME="TOF | 2 | 2.00" SQFTMIN="111" SQFTMAX="222"/>
   </data2>

   <samples>
      <sample ID="001" AVAILDATE="20152901" STATUS="Unavailable" data1TYPE="001" UNITCAT="1X1" SOMEVALUE="50.00" data2ID="141">
         <item1 ID="59" item2="50.00" DESCRIPTION="Sample Description"/>
         <offeredterm LT="2" BASEAMOUNT="1120.00" TOTALCONCESSION="0.00" EFFECTIVESAMPLE="1120.00" CONTYPE="T" CONVALUE="0.00"/>
      </sample>
    <sample ID="002" AVAILDATE="20152901" STATUS="Unavailable" data1TYPE="001" UNITCAT="1X1" SOMEVALUE="50.00" data2ID="141">
         <item1 ID="59" item2="50.00" DESCRIPTION="Sample Description"/>
         <offeredterm LT="2" BASEAMOUNT="1120.00" TOTALCONCESSION="0.00" EFFECTIVESAMPLE="1120.00" CONTYPE="T" CONVALUE="0.00"/>
      </sample>

所以我尝试了几种方法来解析它,但我最终想要的是一个结构化集合,然后我可以运行操作,比如从 data1 中选择所有具有相同 data1TYPE 的项目datatype ID

目前我的代码如下所示:

$XML = Storage::disk('local')->get('data\XML.xml');
$random = collect(json_decode(json_encode((array) simplexml_load_string($XML)), true));

我已经能够检索到这样的对象,然后通过索引循环并为每个 xml 标记构建一个单独的集合。不过这感觉效率不高,而且我不确定以后如何最好地运行比较操作。

有什么想法吗?

【问题讨论】:

  • 有没有办法可以给我们实际的 xml?您提供的示例是格式错误的 xml。

标签: php laravel xml-parsing


【解决方案1】:

欢迎来到 xml 的世界!你这样做的方式是我目前所知道的最好的方式。 xml 到 json 的一个基本示例是您的操作方式:

$xml = simplexml_load_string($xml_string);

$json = json_encode($xml);

$array = json_decode($json,TRUE);

我确实看到您在 simplexml_load_string 调用之前是类型提示数组。有什么原因吗?

此外,当您说您不确定如何进行比较时,您的具体意思是什么?您的 xml 是静态的,意味着永远不会改变,还是在大小和/或范围上发生变化?

【讨论】:

    【解决方案2】:

    我创建了一个可以很好地与 Laravel 配合使用的包,以帮助您将 XML 转换为数组。

    https://github.com/mtownsend5512/xml-to-array

    安装它,你就可以使用 Laravel 的全局辅助函数xml_to_array

    由于您的 XML 格式不正确,我已尽力修复它,以便提供示例:

        $xml = <<<XML
    <?xml version="1.0" encoding="UTF-8"?>
    <community ID="1234" POSTDATE="20180329"
        xmlns="" COMPANY="SAMPLE CO">
        <data1>
            <datatype ID="0001">
                <utpricing LT="1" STARTDATE="20150102" ENDDATE="20160102" BASEAMOUNT="99" CONCESSION="0.00" EFFAMOUNT="99" CONTYPE="SAMPLE" CONVALUE="0.00"/>
                <utpricing LT="1" STARTDATE="20150102" ENDDATE="20160102" BASEAMOUNT="99" CONCESSION="0.00" EFFAMOUNT="99" CONTYPE="SAMPLE" CONVALUE="0.00"/>
                <utpricing LT="1" STARTDATE="20150102" ENDDATE="20160102" BASEAMOUNT="99" CONCESSION="0.00" EFFAMOUNT="99" CONTYPE="SAMPLE" CONVALUE="0.00"/>
                <utpricing LT="1" STARTDATE="20150102" ENDDATE="20160102" BASEAMOUNT="99" CONCESSION="0.00" EFFAMOUNT="99" CONTYPE="SAMPLE" CONVALUE="0.00"/>
            </datatype>
            <datatype ID="0002">
                <utpricing LT="2" STARTDATE="20160102" ENDDATE="20170102" BASEAMOUNT="99" CONCESSION="0.00" EFFAMOUNT="99" CONTYPE="SAMPLE" CONVALUE="0.00"/>
                <utpricing LT="1" STARTDATE="20150102" ENDDATE="20160102" BASEAMOUNT="99" CONCESSION="0.00" EFFAMOUNT="99" CONTYPE="SAMPLE" CONVALUE="0.00"/>
                <utpricing LT="1" STARTDATE="20150102" ENDDATE="20160102" BASEAMOUNT="99" CONCESSION="0.00" EFFAMOUNT="99" CONTYPE="SAMPLE" CONVALUE="0.00"/>
                <utpricing LT="1" STARTDATE="20150102" ENDDATE="20160102" BASEAMOUNT="99" CONCESSION="0.00" EFFAMOUNT="99" CONTYPE="SAMPLE" CONVALUE="0.00"/>
            </datatype>
        </data1>
        <data2>
            <data2 ID="141" NAME="IAM | 1 | 1.00" SQFTMIN="111" SQFTMAX="222"/>
            <data2 ID="142" NAME="ASA | 1 | 1.00" SQFTMIN="111" SQFTMAX="222"/>
            <data2 ID="143" NAME="MPL | 1 | 1.00" SQFTMIN="111" SQFTMAX="222"/>
            <data2 ID="144" NAME="EBI | 1 | 1.00" SQFTMIN="111" SQFTMAX="222"/>
            <data2 ID="145" NAME="TOF | 2 | 2.00" SQFTMIN="111" SQFTMAX="222"/>
        </data2>
        <samples>
            <sample ID="001" AVAILDATE="20152901" STATUS="Unavailable" data1TYPE="001" UNITCAT="1X1" SOMEVALUE="50.00" data2ID="141">
                <item1 ID="59" item2="50.00" DESCRIPTION="Sample Description"/>
                <offeredterm LT="2" BASEAMOUNT="1120.00" TOTALCONCESSION="0.00" EFFECTIVESAMPLE="1120.00" CONTYPE="T" CONVALUE="0.00"/>
            </sample>
            <sample ID="002" AVAILDATE="20152901" STATUS="Unavailable" data1TYPE="001" UNITCAT="1X1" SOMEVALUE="50.00" data2ID="141">
                <item1 ID="59" item2="50.00" DESCRIPTION="Sample Description"/>
                <offeredterm LT="2" BASEAMOUNT="1120.00" TOTALCONCESSION="0.00" EFFECTIVESAMPLE="1120.00" CONTYPE="T" CONVALUE="0.00"/>
            </sample>
        </samples>
    </community>
    XML;
    
    dd(xml_to_array($xml));
    

    现在您的 XML 将是一个可以操作的有效数组。由于您广泛使用属性,您将需要清理大量数据。我建议通过 collect($xml) 将其包装在 Laravel 集合中,然后检查 Laravel's Collection documentation 以找出以您想要的方式转换数据的最佳方法。

    【讨论】:

      猜你喜欢
      • 2016-11-17
      • 1970-01-01
      • 2018-07-03
      • 2021-03-27
      • 2012-07-15
      • 2013-05-29
      • 2012-12-16
      • 2011-09-01
      • 2021-01-02
      相关资源
      最近更新 更多