向变量添加额外的字符串 - PHP

Adding additional string to variable - PHP

这是我的问题。我想创建一个函数,它接受一个包含 xpath 的外部变量,一旦函数运行,我想添加到同一个变量以创建一个计数器。

所以我有外部变量:

 $node = $xmlDoc->xpath('//a:Order');

然后是带有单个参数的函数,该函数将采用外部变量 ($node)。像这样:

function loopXML($node) {
    i=1; //counter variable
}

现在我想向 $node 添加一个计数器,以便它遍历 "Order" 的所有子节点。在函数之外,我会使用:

$child = $xmlDoc->xpath('//a:Order['.$i.']/*'); 

但是在函数内部,我不知道如何连接它。有人知道我该怎么做吗?

编辑: 另外,应该注意的是,我已经创建了一个任意命名空间:

 foreach($xmlDoc->getDocNamespaces() as $strPrefix => $strNamespace) {
     if(strlen($strPrefix)==0) {
         $strPrefix="a"; //Assign an arbitrary namespace prefix.
     }
     $xmlDoc->registerXPathNamespace($strPrefix,$strNamespace);
 }

SimpleXMLElement::xpath() 使用与 SimpleXML 元素关联的节点作为上下文,因此您可以执行如下操作:

foreach ($xmlDoc->xpath('//a:Order') as $order) {
  foreach ($order->xpath('*') as $field) {
    ...
  }
} 

但是 SimpleXMLElement::children() 是元素子节点的列表,因此它 returns 与 Xpath 表达式 * 相同,或者更准确地说 '*[namespace-uri == ""]'。第一个参数是您要获取的子项的命名空间。

foreach ($xmlDoc->xpath('//a:Order') as $order) {
  foreach ($order->children() as $field) {
    ...
  }
}

这可以很容易地重构为一个函数。

function getRecord(SimpleXMLelement $order, $namespace) {
  $result = [];
  foreach ($order->children($namespace) as $field) {
    $result[$field->getName()] = (string)$field;
  }
  return $result;
}

您应该始终依赖于实际的命名空间,而不是前缀。前缀可以更改并且是可选的。

放在一起:

$xml = <<<'XML'
<a:orders xmlns:a="urn:a">
  <a:order>
    <a:foo>bar</a:foo>
    <a:answer>42</a:answer>
  </a:order>
</a:orders>
XML;

$namespace = 'urn:a';

$orders = new SimpleXMLElement($xml);
$orders->registerXpathNamespace('a', $namespace);

function getRecord(SimpleXMLelement $order, $namespace = NULL) {
  $result = [];
  foreach ($order->children($namespace) as $field) {
    $result[$field->getName()] = (string)$field;
  }
  return $result;
} 

foreach ($orders->xpath('//a:order') as $order) {
  var_dump(getRecord($order, $namespace));
}

输出:

array(2) {
  ["foo"]=>
  string(3) "bar"
  ["answer"]=>
  string(2) "42"
}

所以我通过大量谷歌搜索和 ThW 的帮助弄明白了。对于所有帮助的人,谢谢。这是我如何让它工作的:

 $orderPNode = '//a:Order'; 
 $amazonRawXML = 'AmazonRaw.xml';
 $amazonRawCSV = 'AmazonRaw.csv';


function loopXML($xmlDoc, $node, $writeCsv) {
$i = 1;
$xmlDocs = simplexml_load_file($xmlDoc);
$result = [];

foreach($xmlDocs->getDocNamespaces() as $strPrefix => $strNamespace) {
    if(strlen($strPrefix)==0) {
        $strPrefix="a"; //Assign an arbitrary namespace prefix.
    }
$xmlDocs->registerXPathNamespace($strPrefix,$strNamespace);
}

file_put_contents($writeCsv, ""); // Clear contents of csv file after each go

$nodeP = $xmlDocs->xpath($node); 

foreach ($nodeP as $n) {
    $nodeC = $xmlDocs->xpath($node.'['.$i.']/*');
    if($nodeC) {
        foreach ($nodeC as $value) {
            $values[] = $value;
        }
    $write = fopen($writeCsv, 'a'); 
    fputcsv($write, $values);
    fclose($write);

    $values = [];
    $i++;
    } else {
        $result[] = $n;
        $i++;
    }

}
return $result;
}
loopXML($amazonRawXML, $orderPNode, $amazonRawCSV);