PHP SimpleXML递归函数列出孩子和属性 [英] PHP SimpleXML recursive function to list children and attibutes

查看:188
本文介绍了PHP SimpleXML递归函数列出孩子和属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一些帮助SimpleXML调用一个递归函数列出元素名称和属性。创建一个XML配置文件系统,但每个脚本将有自己的配置文件以及一个新的命名约定。所以我需要一个简单的方法来映射所有的元素有属性,所以像例1我需要一个简单的方法来调用所有的进程,但我不知道如何做没有硬编码的元素名称是函数调用。有没有办法递归调用函数来匹配子元素名称?我没有看到xpath功能,但我不知道如何使用这个属性。任何想法?

I need some help on the SimpleXML calls for a recursive function that lists the elements name and attributes. Making a XML config file system but each script will have it's own config file as well as a new naming convention. So what I need is an easy way to map out all the elements that have attributes, so like in example 1 I need a simple way to call all the processes but I don't know how to do this without hard coding the elements name is the function call. Is there a way to recursively call a function to match a child element name? I did see the xpath functionality but I don't see how to use this for attributes. Any ideas?

示例中的XML看起来是否正确?可以像这样构造我的XML?

Also does the XML in the examples look correct? can I structure my XML like this?

示例1:

<application>
  <processes>
    <process id="123" name="run batch A" />
    <process id="122" name="run batch B" />
    <process id="129" name="run batch C" />
  </processes>
  <connections>
    <databases>
      <database usr="test" pss="test" hst="test" dbn="test" />
    </databases>
    <shells>
      <ssh usr="test" pss="test" hst="test-2" />
      <ssh usr="test" pss="test" hst="test-1" />
    </shells>
  </connections>
</application>

示例2:

<config>
  <queues>
    <queue id="1" name="test" />
    <queue id="2" name="production" />
    <queue id="3" name="error" />
  </queues>
</config>

伪代码:

// Would return matching process id
getProcess($process_id) {
  return the process attributes as array that are in the XML
}

// Would return matching DBN (database name)
getDatabase($database_name) {
  return the database attributes as array that are in the XML
}

// Would return matching SSH Host
getSSHHost($ssh_host) {
  return the ssh attributes as array that are in the XML
}

// Would return matching SSH User
getSSHUser($ssh_user) {
  return the ssh attributes as array that are in the XML
}

// Would return matching Queue 
getQueue($queue_id) {
  return the queue attributes as array that are in the XML
}


$ b b

编辑:

我可以传递两个parms吗?第一种方法你建议@Gordon

Can I pass two parms? on the first method you have suggested @Gordon

我刚刚得到了,thnx,见下面

I just got it, thnx, see below

public function findProcessById($id, $name)
{
    $attr = false;
    $el = $this->xml->xpath("//process[@id='$id'][@name='$name']"); // How do I also filter by the name?
    if($el && count($el) === 1) {
        $attr = (array) $el[0]->attributes();
        $attr = $attr['@attributes'];
    }
    return $attr;
}


推荐答案

XML看起来不错。我唯一不会做的是在进程中创建属性,因为它包含空格,应该是一个textnode然后(在我看来)。但由于SimpleXml没有抱怨,我想这可归结为个人偏好。

The XML looks good to me. The only thing I wouldn't do is making name an attribute in process, because it contains spaces and should be a textnode then (in my opinion). But since SimpleXml does not complain about it, I guess it boils down to personal preference.

我可能用DataFinder类,封装XPath查询,例如

I'd likely approach this with a DataFinder class, encapsulating XPath queries, e.g.

class XmlFinder
{
    protected $xml;
    public function __construct($xml)
    {
        $this->xml = new SimpleXMLElement($xml);
    }
    public function findProcessById($id)
    {
        $attr = false;
        $el = $this->xml->xpath("//process[@id='$id']");
        if($el && count($el) === 1) {
            $attr = (array) $el[0]->attributes();
            $attr = $attr['@attributes'];
        }
        return $attr;
    }
    // ... other methods ...
}

然后使用

$finder = new XmlFinder($xml);
print_r( $finder->findProcessById(122) );

输出:

Array
(
    [id] => 122
    [name] => run batch B
)

XPath教程:

  • http://www.w3schools.com/XPath/default.asp

另一种方法是使用 SimpleXmlIterator 迭代元素。 迭代器可以是用其他迭代器修饰,因此您可以:

An alternative would be to use SimpleXmlIterator to iterate over the elements. Iterators can be decorated with other Iterators, so you can do:

class XmlFilterIterator extends FilterIterator
{
    protected $filterElement;
    public function setFilterElement($name)
    {
        $this->filterElement = $name;
    }
    public function accept()
    {
        return ($this->current()->getName() === $this->filterElement);
    }
}

$sxi = new XmlFilterIterator(
           new RecursiveIteratorIterator( 
               new SimpleXmlIterator($xml)));

$sxi->setFilterElement('process');

foreach($sxi as $el) {
    var_dump( $el ); // will only give process elements
}

SplIterators简介:

Introduction to SplIterators:

  • http://www.phpro.org/tutorials/Introduction-to-SPL.html

这篇关于PHP SimpleXML递归函数列出孩子和属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆