doucuodan0897 2016-11-15 18:00
浏览 100
已采纳

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

Here's my problem. I want to create a function that takes an outside variable that contains an xpath and once the function runs I want to add to that same variable to create a counter.

So I have the outside variable:

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

Then the function with a single argument that will take the outside variable ($node). Like so:

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

Now I want to add a counter to $node so that it goes through all of the children of "Order". Outside of the function, I would use:

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

But inside of the function, I have no idea how to concat it. Does anyone have any idea how I could do this?

EDIT: Also, it should be noted that I created an arbitrary namespace already:

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

2条回答 默认 最新

  • dongyou4411 2016-11-15 18:17
    关注

    SimpleXMLElement::xpath() uses the node associated with the SimpleXML element as the context so you can do something like:

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

    But SimpleXMLElement::children() is a list of the element child nodes so it returns the same as the Xpath expression * or to be more exact '*[namespace-uri == ""]'. The first argument is the namespace of the children you would like to fetch.

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

    This can be easily refactored into a function.

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

    You should always depend on the actual namespace, never on the prefix. Prefixes can change and are optional.

    Put all together:

    $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));
    }
    

    Output:

    array(2) {
      ["foo"]=>
      string(3) "bar"
      ["answer"]=>
      string(2) "42"
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效