如何获得元素$ item [" @ attributes"] [" tag"]的价值

时间:2018-01-25 13:10:19

标签: php arrays simplexml

如何拨打$ item [" @ attributes"] [" tag"]?
我收到致命错误:不能将字符串偏移量用作行中的数组:

if ($item["@attributes"]["tag"] == $field)

我的步骤:我收到XML字符串,将其解压缩到SimpleXMLObject:

object(SimpleXMLElement)#6 (1) 
{ 
["rec"]=> object(SimpleXMLElement)#7 (1) 
  { 
    ["datafield"]=> array(1) { 
    [0]=> object(SimpleXMLElement)#10 (3) 
       {
        ["@attributes"]=> array(1) { 
        ["tag"]=> string(2) "99" 
        }   
        ["@attributes"]=> array(1) { 
        ["tag"]=> string(3) "100" 
        } 

        ["subfield"]=> array(3) { 
         [0]=> string(5) "text0" 
         [1]=> string(5) "text1" 
         [2]=> string(4) "test" 
        } 
       } 
       } 
  } 
} 

因为我在SimpleXMLObject中没有属性[code],所以我把它转换为数组,找到[tag] =" 100"并更改["代码"]或如果code = z不存在则创建它并插入我应该更改或创建的值:

array(1) {
  ["hold"]=> array(1) { 
     ["rec"]=> array(1){ 
      ["datafield"]=> array(2) { 
      [0]=> array(2) 
         { 
          ["subfield"]=> array(1) { 
           [0]=> array(2) { 
              ["@value"]=> string(4) "test" 
              ["@attributes"]=> array(1){ 
              ["code"]=> string(1) "z" 
              } 
             } 
         } 
           ["@attributes"]=> array(1) { 
             ["tag"]=> string(3) "100" 
            } 
          } 
        } 
     } 
 } 
} 

这是我访问数组的PHP代码:

foreach ($xml_ray['hold']['rec'] as $key_item => $item) {
   if ($item["@attributes"]["tag"] == $field) { // Line where I get the ERROR
      foreach ($item['subfield'] as $key_subfield => $subfield) {
          $code = $subfield['@attributes']['code'];
          $value = $subfield['@value'];
               //  ....       
     if ($checksum==2 && $code==$subfield_file) {
           $checksum++;
          }

        if ($checksum == 3) { $xml_hold_ray['hold']['rec'][$key_item]['subfield'][$key_subfield]['@value'] = $new_code;
          }
            }

         }
      }

Origin XML:

  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <hold>
    <rec>
      <datafield ind1=" " ind2=" " tag="99">
       <subfield code="a">text</subfield>
      </datafield>
      <datafield ind1="1" ind2=" " tag="100">
        <subfield code="b">text0</subfield>
        <subfield code="c">text1</subfield>
        <subfield code="z">test2</subfield>
      </datafield>
    </rec>
    </hold>

了解其工作的完整代码:

 foreach ($xml_ray['hold']['rec'] as $key_item => $item) {

      if ($item["@attributes"]["tag"] == $field) {
  $info_msg = "FIELD: $field <br />";
    $outcame_msg .="Found correct field $field<br />";
  foreach ($item['subfield'] as $key_subfield => $subfield) {
      $code = $subfield['@attributes']['code'];
    $value = $subfield['@value'];
      $info_holding_msg.="$code = $value<br />";

      if ($value==$li) {
    $outcame_msg .= "Found correct li in subfield $code<br />";
    $checksum++;
    }
      if ($value==$loc) {
    $outcame_msg .= "Found correct loc in subfield $code<br />";
    $checksum++;
    }

       if ($checksum==2 && $code==$subfield_file) {

       $outcame_msg .= "Found subfield $code with value: $value<br />";
       $checksum++;
      }

    if ($checksum == 3) {

    $xml_ray['hold']['rec'][$key_item]['subfield'][$key_subfield]['@value'] = $new_code;
    $outcame_msg.="data found, changing data accepted.";
      }           
        }         
     }
   }

更新新XML:

$data ='<holds total="4">
<hold link="#">
<hold_id>0000000000000000</hold_id>
<lib desc="Lib">text</lib>
<loc desc="Lib2">text1</loc>
<sup>false</sup>
</hold>
<hold link="#">
<hold_id>0000000000000000</hold_id>
<lib desc="Lib">text</lib>
<loc desc="Lib2">text1</loc>
<sup>false</sup>
</hold>
<hold link="#">
<hold_id>0000000000000000</hold_id>
<lib desc="Lib">text3</lib>
<loc desc="Lib2">text4</loc>
<sup>false</sup>
</hold>   
</holds>';

1 个答案:

答案 0 :(得分:0)

使用SimpleXML,这是访问数据的方法

$data = <<< XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<hold> 
<rec>
  <datafield ind1=" " ind2=" " tag="99">
   <subfield code="a">text</subfield>
  </datafield>
  <datafield ind1="1" ind2=" " tag="100">
    <subfield code="b">text0</subfield>
    <subfield code="c">text1</subfield>
    <subfield code="z">test2</subfield>
  </datafield>
</rec>
</hold>
XML;

$xml_ray = simplexml_load_string($data);

// A test value
$field = "100";
$checksum=2;
$new_code = 't1';
$subfield_file="z";

// Loop through all the <datafield> elements
foreach ( $xml_ray->rec->datafield as $item ) {
    if ( $item['tag'] == $field )    {
        $replaced = false;
        foreach ($item->subfield as $subfield) {
            if ($subfield['code']==$subfield_file) {
                $subfield[0] = $new_code;
                $replaced = true;
            }
        }
        if ( $replaced == false )   {
            $newItem = $item->addChild("subfield", $new_code);
            $newItem->addAttribute("code", $subfield_file);
        }
    }
}

查看您使用->rec访问子元素和['tag']访问属性的方式。

我不是百分之百确定您使用中间位代码做了什么,但我试图添加我认为您正在做的事情。如果该代码不存在,则此代码不会添加它,我不确定$checksum字段处理的工作原理。

如何使用XPath的两个例子......

$match = $xml_ray->xpath("//datafield[subfield[@code='z']]");
if ( count($match) > 0 )    {
    echo "Found match";
}
else    {
    echo "No match found";
}
$match = $xml_ray->xpath("//datafield[@tag='100'][subfield[@code='z1']]");
if ( count($match) > 0 )    {
    echo "Found match";
}
else    {
    echo "No match found";
}

第一个(//datafield[subfield[@code='z']])匹配任何数据字段元素与子字段,该子字段具有值为“z”的属性代码。这会找到一个元素,所以打印'Found Match'。

第二个(//datafield[@tag='100'][subfield[@code='z1']])匹配任何具有tag属性= 100的数据字段元素和一个代码='z1'的子字段。这没有找到元素,所以打印'找不到匹配'。

更新: 如果要选择属性标记= 100的数据字段元素的值和带有代码=“z”的sibfield,则...

$match = $xml_ray->xpath("//datafield[@tag='100']/subfield[@code='z']");
echo (string)$match[0];

我之前稍微改变了XPath,但是这个XPath给了......

test2