XML Parsing - Unable to retrieve value of node

淺唱寂寞╮ 提交于 2019-12-13 08:47:51

问题


I'm trying to determine why it is that I can not get the value of a node within my XML file. I'm using the following PHP code to parse my XML file...

<?php
error_reporting(E_ALL); 
ini_set( 'display_errors','1');
libxml_use_internal_errors(true);
libxml_clear_errors();

// create the reader object
$reader = new XMLReader();

// reader the XML file.
$reader->open('test.xml');

// start reading the XML File.
while($reader->read()) {
    // take action based on the kind of node returned
   switch($reader->nodeType) {
       // read more http://uk.php.net/manual/en/class.xmlreader.php#xmlreader.constants.element
       case (XMLREADER::ELEMENT):
              // get the name of the node.
              $node_name = $reader->name;
              // move the pointer to read the next item
              $reader->read();
              // action based on the $node_name
              if ($node_name == 'PartNumber') {
                $reader->read();
                $data['PartNumber'] = $reader->value;
                var_dump($data);
              };
           break;
       case (XMLREADER::END_ELEMENT):
            // do something based on when the element closes.
            break;
   }
}

?>

An example of my XML data is below...

<Items>
  <Item MaintenanceType="C">
    <HazardousMaterialCode>N</HazardousMaterialCode>
    <ItemLevelGTIN GTINQualifier="UP">090127000380</ItemLevelGTIN>
    <PartNumber>0-1848-1</PartNumber>
    <BrandAAIAID>BBVL</BrandAAIAID>
    <BrandLabel>Holley</BrandLabel>
    <PartTerminologyID>5904</PartTerminologyID>
    <Descriptions>
      <Description MaintenanceType="C" DescriptionCode="DES" LanguageCode="EN">Street Carburetor</Description>
      <Description MaintenanceType="C" DescriptionCode="SHO" LanguageCode="EN">Crb</Description>
    </Descriptions>
    <Prices>
      <Pricing MaintenanceType="C" PriceType="JBR">
        <PriceSheetNumber>L30779-13</PriceSheetNumber>
        <CurrencyCode>USD</CurrencyCode>
        <EffectiveDate>2013-01-01</EffectiveDate>
        <Price UOM="PE">462.4600</Price>
      </Pricing>
      <Pricing MaintenanceType="C" PriceType="RET">
        <PriceSheetNumber>L30779-13</PriceSheetNumber>
        <CurrencyCode>USD</CurrencyCode>
        <EffectiveDate>2013-01-01</EffectiveDate>
        <Price UOM="PE">380.5500</Price>
      </Pricing>
      <Pricing MaintenanceType="C" PriceType="WD1">
        <PriceSheetNumber>L30779-13</PriceSheetNumber>
        <CurrencyCode>USD</CurrencyCode>
        <EffectiveDate>2013-01-01</EffectiveDate>
        <Price UOM="PE">314.4700</Price>
      </Pricing>
    </Prices>
    <ExtendedInformation>
      <ExtendedProductInformation MaintenanceType="C" EXPICode="CTO" LanguageCode="EN">US</ExtendedProductInformation>
      <ExtendedProductInformation MaintenanceType="C" EXPICode="NPC" LanguageCode="EN">A</ExtendedProductInformation>
      <ExtendedProductInformation MaintenanceType="C" EXPICode="HTS" LanguageCode="EN">8409914000</ExtendedProductInformation>
      <ExtendedProductInformation MaintenanceType="C" EXPICode="NAF" LanguageCode="EN">B</ExtendedProductInformation>
    </ExtendedInformation>
    <ProductAttributes>
      <ProductAttribute MaintenanceType="C" AttributeID="SKU" LanguageCode="EN">BBVL0-1848-1</ProductAttribute>
      <ProductAttribute MaintenanceType="C" AttributeID="ModDate" LanguageCode="EN">2012-12-31</ProductAttribute>
    </ProductAttributes>
    <Packages>
      <Package MaintenanceType="C">
        <PackageLevelGTIN>00090127000380</PackageLevelGTIN>
        <PackageUOM>EA</PackageUOM>
        <QuantityofEaches>1</QuantityofEaches>
        <Dimensions UOM="IN">
          <Height>7.5000</Height>
          <Width>11.0000</Width>
          <Length>12.2500</Length>
        </Dimensions>
        <Weights UOM="PG">
          <Weight>13.500</Weight>
          <DimensionalWeight>6.09</DimensionalWeight>
        </Weights>
      </Package>
    </Packages>
  </Item>
</Items>

The var_dump of $data shows the following...

array(1) { ["PartNumber"]=> string(0) "" }

There are no errors being reported.

May someone point me in the direction of what I'm missing?


回答1:


You forgot to define $data = array();

<?php
error_reporting(E_ALL); 
ini_set( 'display_errors','1');
libxml_use_internal_errors(true);
libxml_clear_errors();

$data = array(); //notice this???

// create the reader object
$reader = new XMLReader();

// reader the XML file.
$reader->open('test.xml');

// start reading the XML File.
while($reader->read()) {
    // take action based on the kind of node returned
   switch($reader->nodeType) {
       // read more http://uk.php.net/manual/en/class.xmlreader.php#xmlreader.constants.element
       case (XMLREADER::ELEMENT):
              // get the name of the node.
              $node_name = $reader->name;
              // move the pointer to read the next item
              $reader->read();
              // action based on the $node_name
              if ($node_name == 'PartNumber') {
                $reader->read();
                $data['PartNumber'] = $reader->value;
                var_dump($data);
              };
           break;
       case (XMLREADER::END_ELEMENT):
            // do something based on when the element closes.
            break;
   }
}

?>



回答2:


If you're booked to use XMLReader (e.g. because of having really large XML files) I normally suggest to use a library called XMLReaderIterator which allows you to concentrate on parsing your data, not reading your XML. For your example code this is just really some little code:

require('xmlreader-iterators.php'); // https://github.com/hakre/XMLReaderIterator/tree/master/build/include

$xmlFile = "xmlreader-17187636.xml";

$reader = new XMLReader();
$reader->open($xmlFile);

/* @var $partNumbers XMLReaderNode[] */
$partNumbers = new XMLElementIterator($reader, 'PartNumber');

foreach($partNumbers as $partNumber) {
    echo " * ",  $partNumber->readString(), "\n";
}

This shows how to use an XMLElementIterator to iterate over all elements named PartNumber and then reading their string value. The output in this example case is:

 * 0-1848-1

because you've got a single part-number element in the XML.

The example also shows that there still is the XML reader so you can do everything with it as well within the foreach and there are also other iterators that allow you to query elements, atttributes and even run shallow xpath queries.

Last time I suggested that library was in:

  • parsing/scanning through a 17gb xml file

If you don't want to use the whole library, you find the code inside the XMLReaderNode::readString() method which also shows how to get the value backwards-compatible which makes your code more inter-operable which is a benefit of that library. See as well XMLReader::readString().




回答3:


If the XML document is not huge, why not use SimpleXMLElement's simplexml_load_string() or even DOMDocument's ->loadXML(). And use XPath queries against them to get any node you want. The XMLReader should be used when you are dealing with very large files that should not be preloaded but read sequentially.




回答4:


use simplexmland xpath to retrieve the value:

$xml = simplexml_load_string($x); // assume XML in $x
$pns = $xml->xpath("//PartNumber");

now, $pns contains an array of all <PartNumber> values.

To retrieve only the 1st <PartNumber>, do:

$pn = $xml->xpath("//PartNumber")[0]; // with PHP >= 5.4

See it working: http://3v4l.org/I7eKQ



来源:https://stackoverflow.com/questions/17187636/xml-parsing-unable-to-retrieve-value-of-node

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!