Foreach对不起PHP的对象数组

时间:2017-01-07 09:42:45

标签: php xml

所以我在$ xml中有XML。它看起来像这样:

http://localhost:8888/?purp=oclcn&xml=<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<record xmlns="http://www.loc.gov/MARC21/slim">
    <leader>00000cam a2200000 a 4500</leader>
    <controlfield tag="001">33333502</controlfield>
    <controlfield tag="008">951010s1996    vtua     b    001 0 eng  </controlfield>
    <datafield ind1=" " ind2=" " tag="010">
      <subfield code="a">   95045582 </subfield>
    </datafield>
    <datafield ind1=" " ind2=" " tag="020">
      <subfield code="a">1858983274</subfield>
    </datafield>
    <datafield ind1=" " ind2=" " tag="020">
      <subfield code="a">9781858983271</subfield>
    </datafield>
    <datafield ind1="0" ind2="0" tag="245">
      <subfield code="a">Economic sociology /</subfield>
      <subfield code="c">edited by Richard Swedberg.</subfield>
    </datafield>
    <datafield ind1=" " ind2=" " tag="260">
      <subfield code="a">Cheltenham, Glos, UK ;</subfield>
      <subfield code="a">Brookfield, Vt., US :</subfield>
      <subfield code="b">E. Elgar Pub. Co.,</subfield>
      <subfield code="c">©1996.</subfield>
    </datafield>
    <datafield ind1=" " ind2=" " tag="300">
      <subfield code="a">xv, 574 pages :</subfield>
      <subfield code="b">illustrations ;</subfield>
      <subfield code="c">25 cm.</subfield>
    </datafield>
    <datafield ind1="1" ind2=" " tag="490">
      <subfield code="a">The international library of critical writings in sociology ;</subfield>
      <subfield code="v">5</subfield>
    </datafield>
    <datafield ind1="1" ind2=" " tag="490">
      <subfield code="a">An Elgar reference collection</subfield>
    </datafield>
    <datafield ind1=" " ind2=" " tag="500">
      <subfield code="a">A collection of journal articles previously published between 1940-1994.</subfield>
    </datafield>
    <datafield ind1=" " ind2="0" tag="650">
      <subfield code="a">Economics</subfield>
      <subfield code="x">Sociological aspects.</subfield>
    </datafield>
    <datafield ind1=" " ind2="0" tag="650">
      <subfield code="a">Sociology.</subfield>
    </datafield>
    <datafield ind1=" " ind2="0" tag="650">
      <subfield code="a">Economics.</subfield>
    </datafield>
    <datafield ind1=" " ind2="6" tag="650">
      <subfield code="a">Économie politique</subfield>
      <subfield code="x">Aspect sociologique.</subfield>
    </datafield>
    <datafield ind1=" " ind2="6" tag="650">
      <subfield code="a">Sociologie.</subfield>
    </datafield>
    <datafield ind1=" " ind2="6" tag="650">
      <subfield code="a">Économie politique.</subfield>
    </datafield>
    <datafield ind1=" " ind2="7" tag="650">
      <subfield code="a">Economics.</subfield>
      <subfield code="2">fast</subfield>
      <subfield code="0">(OCoLC)fst00902116</subfield>
    </datafield>
    <datafield ind1=" " ind2="7" tag="650">
      <subfield code="a">Economics</subfield>
      <subfield code="x">Sociological aspects.</subfield>
      <subfield code="2">fast</subfield>
      <subfield code="0">(OCoLC)fst00902213</subfield>
    </datafield>
    <datafield ind1=" " ind2="7" tag="650">
      <subfield code="a">Sociology.</subfield>
      <subfield code="2">fast</subfield>
      <subfield code="0">(OCoLC)fst01123875</subfield>
    </datafield>
    <datafield ind1="1" ind2="7" tag="650">
      <subfield code="a">Economische sociologie.</subfield>
      <subfield code="2">gtt</subfield>
    </datafield>
    <datafield ind1=" " ind2="7" tag="650">
      <subfield code="a">Sociologie économique.</subfield>
      <subfield code="2">ram</subfield>
    </datafield>
    <datafield ind1=" " ind2="7" tag="650">
      <subfield code="a">Économie politique</subfield>
      <subfield code="x">Sociologie.</subfield>
      <subfield code="2">ram</subfield>
    </datafield>
    <datafield ind1="0" ind2="7" tag="650">
      <subfield code="a">Wirtschaftssoziologie.</subfield>
      <subfield code="2">swd</subfield>
    </datafield>
    <datafield ind1=" " ind2="4" tag="650">
      <subfield code="a">Sociologie.</subfield>
    </datafield>
    <datafield ind1=" " ind2="4" tag="650">
      <subfield code="a">Économie politique.</subfield>
    </datafield>
    <datafield ind1=" " ind2="4" tag="650">
      <subfield code="a">Économie politique - Aspect sociologique.</subfield>
    </datafield>
    <datafield ind1="0" ind2="7" tag="650">
      <subfield code="a">Wirtschaftssoziologie.</subfield>
      <subfield code="0">(DE-588)4066514-8</subfield>
      <subfield code="2">gnd</subfield>
    </datafield>
    <datafield ind1="1" ind2=" " tag="700">
      <subfield code="a">Swedberg, Richard.</subfield>
    </datafield>
  </record>

我正在努力获得&#34; tag&#34;的价值。每个元素的属性。但是,foreach循环不起作用。它只与008hello相呼应,而不是更多。怎么样?

$dataf = $xml->getElementsByTagName("datafield");
$controlf = $xml->getElementsByTagName("controlfield");


        $count = $dataf->length + $controlf->length;

我将每个DOMNodeList的内容放入一个数组中,这样我就可以将它们合并在一起:             $ DOMarray = array();

        $i = 1;
        while ($i <= $controlf->length) {
        $p = $controlf->item($i);
        $DOMarray[] = $p;
        $i++;
}

        $i = 1;
        while ($i <= $dataf->length) {
        $p = $dataf->item($i);
        $DOMarray[] = $p;
        $i++;
}

现在我希望获得每个元素的属性标记的值:

echo get_class($DOMarray[$number]);
echo sizeof($DOMarray);
foreach($DOMarray as $DOMe) {
    echo $DOMe->getAttribute("tag");
    echo "hello";
}
// echo $DOMarray[$number]->getAttribute("tag");
}
}

2 个答案:

答案 0 :(得分:1)

问题出在你的循环设置上。

在您的数据中, plz share ur idea.... 数组中有2个元素,但是,因为您在$controlf开始计数,所以您正在跳过第一个。这就是您获得1而不是第一个值008的原因。

001

要解决此问题,请在$i = 1; while ($i <= $controlf->length) { $p = $controlf->item($i); $DOMarray[] = $p; $i++; } 处启动您的计数器并使用0而不是<

<=

通常,在使用循环时,通常使用$i = 0; while ($i < $controlf->length) { $p = $controlf->item($i); $DOMarray[] = $p; $i++; } ,因为数组的索引是从零开始的,而length属性是实际的元素数。所以length属性总是比最高索引值高1。

此外,在这种情况下,您可能会发现使用<更清洁一点。以下内容相当于上面的代码:

foreach

答案 1 :(得分:0)

您的XML使用命名空间,因此您也应该使用命名空间感知方法。这意味着getElementsByTagNameNS()。我建议在关联数组中定义命名空间。这里不需要使用循环将DOMNodeList对象转换为数组。 DOMNodeList实现了迭代器,这里有一个函数iterator_to_array()来完成那个工作。但是为什么要创建节点数组,你可以迭代DOMNodeList并阅读tag属性。

$xmlns = [
  'slim' => 'http://www.loc.gov/MARC21/slim'
];
$document = new DOMDocument();
$document->loadXml($xml);

$result = [];
$nodes = $document->getElementsByTagNameNS($xmlns['slim'], 'controlfield');
foreach ($nodes as $node) {
  $result[] = $node->getAttribute('tag');
}
$nodes = $document->getElementsByTagNameNS($xmlns['slim'], 'datafield');
foreach ($nodes as $node) {
  $result[] = $node->getAttribute('tag');
}

var_dump($result);

输出:

array(29) {
  [0]=>
  string(3) "001"
  [1]=>
  string(3) "008"
  [2]=>
  string(3) "010"
  [3]=>
  string(3) "020"
  ...

更简单的方法是使用Xpath。属性是节点,Xpath允许您直接获取它们。

$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
$xpath->registerNamespace('slim', 'http://www.loc.gov/MARC21/slim');

$result = [];
$expression = '/slim:record/slim:controlfield/@tag|/slim:record/slim:datafield/@tag';
foreach ($xpath->evaluate($expression) as $attribute) {
  $result[] = $attribute->value;
}

var_dump($result);

Xpath 1.0没有默认命名空间的概念,因此您需要为其注册前缀。之后,您可以使用位置路径过滤DOM中的节点。 /slim:record/slim:controlfield获取所有controlfield个元素。 @tag获取标记属性节点。 |充当过滤器表达式的 OR