【问题标题】:Extracting XML Data with Foreach Loops Based on a Specific Tag ID使用基于特定标记 ID 的 Foreach 循环提取 XML 数据
【发布时间】:2019-03-08 04:59:35
【问题描述】:

我正在尝试根据标记 <styleId> 的值从 XML 文档中提取数据。

如果<styleId> = 292015 我想要列出value 数据,同样如果<styleId> = 292016 我想要列出value 数据。这是一个例子:

<technicalSpecification>
  <titleId>6</titleId>
  <value value="All-Wheel Drive" condition="">
   <styleId>292015</styleId>
   <styleId>292016</styleId>
  </value>
</technicalSpecification>

因此,如果我调用所有包含&lt;styleId&gt;292015&lt;/styleId&gt;value 数据,我将收到All-Wheel Drive。此外,如果我调用所有包含&lt;styleId&gt;292016&lt;/styleId&gt;value 数据,我也会收到All-Wheel Drive

这是我从中提取的完整 XML 文档。

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
  <VehicleDescription country="US" language="en" modelYear="2008" bestMakeName="Audi" bestModelName="S4" bestStyleName="5dr Avant Wgn" xmlns="urn:description7b.services.chrome.com">
     <responseStatus responseCode="Successful" description="Successful"/>

     <style id="292015" modelYear="2008" name="5dr Avant Wgn Man" nameWoTrim="5dr Avant Wgn Man" mfrModelCode="8ED549" fleetOnly="false" modelFleet="false" passDoors="4" altBodyType="Station Wagon" drivetrain="All Wheel Drive">
        <division id="4">Audi</division>
        <subdivision id="5020">Audi</subdivision>
        <model id="17308">S4</model>
        <basePrice unknown="false" invoice="46137.0" msrp="49610.0" destination="775.0"/>
        <bodyType primary="true" id="7">Station Wagon</bodyType>
        <marketClass id="53">Small Wagon</marketClass>
        <acode>USB80AUC085A0</acode>
     </style>
     <style id="292016" modelYear="2008" name="5dr Avant Wgn Auto" nameWoTrim="5dr Avant Wgn Auto" mfrModelCode="8ED54L" fleetOnly="false" modelFleet="false" passDoors="4" altBodyType="Station Wagon" drivetrain="All Wheel Drive">
        <division id="4">Audi</division>
        <subdivision id="5020">Audi</subdivision>
        <model id="17308">S4</model>
        <basePrice unknown="false" invoice="47162.0" msrp="50710.0" destination="775.0"/>
        <bodyType primary="true" id="7">Station Wagon</bodyType>
        <marketClass id="53">Small Wagon</marketClass>
        <acode>USB80AUC085A1</acode>
     </style>
     <technicalSpecification>
        <titleId>1</titleId>
        <value value="Audi S4" condition="-PT">
           <styleId>292015</styleId>
           <styleId>292016</styleId>
        </value>
        <value value="Audi S4" condition="">
           <styleId>292015</styleId>
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>2</titleId>
        <value value="5 Door Wagon" condition="">
           <styleId>292015</styleId>
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>6</titleId>
        <value value="All-Wheel Drive" condition="">
           <styleId>292015</styleId>
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>7</titleId>
        <value value="Small Station Wagon" condition="">
           <styleId>292015</styleId>
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>8</titleId>
        <range min="5.0" max="5.0"/>
        <value value="5" condition="">
           <styleId>292015</styleId>
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>9</titleId>
        <range min="90.8" max="90.8"/>
        <value value="90.8" condition="">
           <styleId>292015</styleId>
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>10</titleId>
        <range min="4012.0" max="4101.0"/>
        <value value="4012" condition="">
           <styleId>292015</styleId>
        </value>
        <value value="4101" condition="">
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>26</titleId>
        <range min="13.0" max="14.0"/>
        <value value="13" condition="">
           <styleId>292015</styleId>
        </value>
        <value value="14" condition="">
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>27</titleId>
        <range min="20.0" max="21.0"/>
        <value value="20" condition="">
           <styleId>292015</styleId>
        </value>
        <value value="21" condition="">
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>31</titleId>
        <value value="- TBD -" condition="">
           <styleId>292015</styleId>
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>32</titleId>
        <value value="- TBD -" condition="">
           <styleId>292015</styleId>
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>33</titleId>
        <value value="- TBD -" condition="">
           <styleId>292015</styleId>
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>34</titleId>
        <value value="- TBD -" condition="">
           <styleId>292015</styleId>
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>40</titleId>
        <value value="" condition="">
           <styleId>292015</styleId>
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>41</titleId>
        <value value="Gas V8" condition="">
           <styleId>292015</styleId>
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>42</titleId>
        <value value="4.2L/254" condition="">
           <styleId>292015</styleId>
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>43</titleId>
        <value value="SEFI" condition="">
           <styleId>292015</styleId>
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>48</titleId>
        <value value="340 @ 6800" condition="">
           <styleId>292016</styleId>
        </value>
        <value value="340 @ 7000" condition="">
           <styleId>292015</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>49</titleId>
        <value value="302 @ 3500" condition="">
           <styleId>292015</styleId>
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>51</titleId>
        <value value="" condition="">
           <styleId>292015</styleId>
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>52</titleId>
        <range min="6.0" max="6.0"/>
        <value value="6" condition="">
           <styleId>292015</styleId>
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>53</titleId>
        <value value="Manual" condition="">
           <styleId>292015</styleId>
        </value>
        <value value="Automatic" condition="">
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>54</titleId>
        <value value="" condition="">
           <styleId>292015</styleId>
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>56</titleId>
        <range min="3.67" max="4.17"/>
        <value value="3.67" condition="">
           <styleId>292015</styleId>
        </value>
        <value value="4.17" condition="">
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>57</titleId>
        <range min="2.05" max="2.34"/>
        <value value="2.05" condition="">
           <styleId>292015</styleId>
        </value>
        <value value="2.34" condition="">
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>58</titleId>
        <range min="1.46" max="1.52"/>
        <value value="1.46" condition="">
           <styleId>292015</styleId>
        </value>
        <value value="1.52" condition="">
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
     <technicalSpecification>
        <titleId>59</titleId>
        <range min="1.13" max="1.14"/>
        <value value="1.13" condition="">
           <styleId>292015</styleId>
        </value>
        <value value="1.14" condition="">
           <styleId>292016</styleId>
        </value>
     </technicalSpecification>
  </VehicleDescription>

这是我目前的一些 PHP:

<?php

  $xml = file_get_contents('data.xml');
  $dom = new DOMDocument();
  $dom->loadXML($xml);

?>

<?php


 foreach ( $dom->getElementsByTagName('technicalSpecification') as $techSpec )   {
  if ($techSpec->getElementsByTagName('styleId')->item(0)->nodeValue == '292015'){
  $techDatass = $techSpec->getElementsByTagName('value')->item(0)->getAttribute("value");
  $techData[] = $techDatass;
  }
 }
 foreach ($techData as $finalTech){
  echo $finalTech."<br>";
 }

 echo "<br><br>";

?>

这将返回包含&lt;styleId&gt;292015&lt;/styleId&gt; 的大多数值数据。但是,它不会返回与该标签相关的所有值数据。此外,如果我将292016 插入其中,它只会返回一个值。我相信这是因为item(0)。我不确定如何构造循环,以便如果292016 出现在292015 之后,它仍然会识别并显示value 数据。

任何帮助将不胜感激。

【问题讨论】:

  • @nigelren 有什么想法吗?

标签: php arrays xml foreach domdocument


【解决方案1】:

如果你只想坚持使用 DOMDocument,你可以添加一些嵌套循环:

$dom = new DOMDocument();
$dom->loadXml($xml);
$techData = [];

foreach ( $dom->getElementsByTagName('technicalSpecification') as $techSpecElement )   {
    foreach($techSpecElement->getElementsByTagName('value') as $valueElement) {
        foreach($valueElement->getElementsByTagName('styleId') as $styleIdElement) {
            // check the value of the styleId here
            if (in_array($styleIdElement->nodeValue, ['292015','292016'])) {
                // if it matches, get the parent value element's value
                $techData[] = $valueElement->getAttribute("value");
            }
        }
    }
}

【讨论】:

  • 没问题。 DOMXPath 也非常强大,但有时循环遍历 DOM 是最简单的,尤其是在 XML 结构有些简单的情况下。
  • 我想我可以将我的代码转移到 DOMXPath。每个人都建议我这样做。
【解决方案2】:

使用DOMXPath

$xpath = new DOMXPath($doc);

// We starts from the root element
$query = '//value/styleId';
$entries = $xpath->query($query);

foreach ($entries as $entry) {
    $styleId = $entry->nodeValue;
    $value = $entry->parentNode->attributes->getNamedItem("value");
    echo "$styleId -> $value\n";
}

【讨论】:

  • 感谢您的回复!它不适合我。见这里:sandbox.onlinephpfunctions.com/code/…
  • 您仍然必须像在原始代码中一样创建DOMDocument
  • 创建DOMDocument 后仍然没有结果。见这里:sandbox.onlinephpfunctions.com/code/…
  • 您在链接代码中使用的 XML 文档与您的问题不匹配,因此您必须调整 xpath 查询。
  • 我从这个问题复制并粘贴了它。
猜你喜欢
  • 2019-03-07
  • 2019-03-08
  • 1970-01-01
  • 2019-10-18
  • 2019-01-14
  • 1970-01-01
  • 2019-11-03
  • 2018-02-27
  • 1970-01-01
相关资源
最近更新 更多