-1

need to parse a large XML document and add the values into a SQL db. I'd like to store all of the key/value pairs in a sql db to simplify my PHP code. Not all of the nodes are present in all of the XML records, so want to iterate through the DB values, i.e. classification->pn, then see if the node exists, then add the value to the SQL insert. Can't get it to work:

So instead of:

foreach($xmldata->children() as $node) {  
  if(isset($node->classification->pn)) {
     ...
  }
}

I want to do:

foreach($xmldata->children() as $node) {  
  if(isset($node->$sqlrow['childnodename'])) {
     ...
  }
}

where $sqlrow['childnodename'] = "classification->pn" as stored in my sql table.

Tried treating it like a dynamic variable, using $$childnodename, etc., but nothing seems to work.

user3783243
  • 5,368
  • 5
  • 22
  • 41
  • You can solve this with XPath: https://www.php.net/manual/en/simplexmlelement.xpath.php – Bademeister Jul 11 '23 at 17:18
  • Welcome to Stack Overflow (SO). You would need to eval the string, and that you should not consider. However, why not store it as xpath expression as @Bademeister also suggested: `classification/pn`. such an expression you can _easily_ obtain with SimpleXMLElement (and foreach over the result). For your question why this does not work, I've added an answer. If you want a more concrete answer, consider to create a [mre]. – hakre Jul 11 '23 at 21:04

1 Answers1

-1

What you want to do, you can't write in PHP as an expression:

foreach($xmldata->children() as $node) {  
  if(isset($node->$sqlrow['childnodename'])) {
     ...
  }
}

where $sqlrow['childnodename'] = "classification->pn" (as stored in your mysql table).

What you would need to write is:

$parts = explode('->', $sqlrow['childnodename']);
foreach($xmldata->children() as $node) {
  $cursor = $node;
  foreach($parts as $part) {
    if (!$cursor->$part) {
        continue 2; # skip to next ->children() $node
    }
    $cursor = $cursor->$part;
  }
  // $cursor is here the descendant (children, grandchildren, etc.)  you're looking for
}

(exemplary only)

This is because "->" within "classification->pn" is taken as part of the XML elment-name in SimpleXMLElement which is invalid as the > character is never allowed for XML element names.

You need to handle the traversal more verbosely as otherwise SimpleXMLElement can only refuse your request, simply because it is not an XML element name.

Cf. Allowed symbols in XML element name

hakre
  • 193,403
  • 52
  • 435
  • 836