在PHP中从类构建XML文件

时间:2012-10-09 14:08:39

标签: php xml class

我想知道是否有人知道如何从类列表中动态构建XML文件?

这些类包含公共变量,看起来像这样。

class node {
    public $elementname;
}

我注意到某些类的名称与变量相同,在这种情况下,节点将是节点的子节点元素:

class data {
   public $dataaset;
}

class dataset {
    public $datasetint;
}

将是:

 <data>
  <dataset>datasetint</dataset>
 </data>

也许是SimpleXML中的东西?

1 个答案:

答案 0 :(得分:7)

我能想到连接2个或更多不相关类的唯一解决方案是使用Annotations

默认情况下,PHP不支持注释,但目前位于RFC (Request for Comments: Class Metadata),但支持或拒绝缩短时间,您可以使用ReflectionClass&amp; Comments功能

示例如果您有3个这样的类

class Data {
    /**
     *
     * @var Cleaner
     */
    public $a;
    /**
     *
     * @var Extraset
     */
    public $b;
    public $runMe;

    function __construct() {
        $this->runMe = new stdClass();
        $this->runMe->action = "RUN";
        $this->runMe->name = "ME";
    }
}
class Cleaner {
    public $varInt = 2;
    public $varWelcome = "Hello World";

    /**
     *
     * @var Extraset
     */
    public $extra;
}
class Extraset {
    public $boo = "This is Crazy";
    public $far = array(1,2,3);
}

然后你可以运行像这样的代码

$class = "Data";
$xml = new SimpleXMLElement("<$class />");
getVariablesXML($class, $xml);
header("Content-Type: text/xml");
$xml->asXML('data.xml');
echo $xml->asXML();

输出

<?xml version="1.0"?>
<Data>
  <Cleaner name="a">
    <varInt type="integer">2</varInt>
    <varWelcome type="string">Hello World</varWelcome>
    <Extraset name="extra">
      <boo type="string">This is Crazy</boo>
      <far type="serialized">a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}</far>
    </Extraset>
  </Cleaner>
  <Extraset name="b">
    <boo type="string">This is Crazy</boo>
    <far type="serialized">a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}</far>
  </Extraset>
  <runMe type="serialized">O:8:"stdClass":2:{s:6:"action";s:3:"RUN";s:4:"name";s:2:"ME";}</runMe>
</Data>

使用的功能

function getVariablesXML($class, SimpleXMLElement $xml) {
    $reflect = new ReflectionClass($class);
    foreach ( $reflect->getProperties(ReflectionProperty::IS_PUBLIC) as $property ) {
        $propertyReflect = $reflect->getProperty($property->getName());
        preg_match("/\@var (.*)/", $propertyReflect->getDocComment(), $match);
        $match and $match = trim($match[1]);
        if (empty($match)) {
            $value = $property->getValue(new $class());
            if (is_object($value) || is_array($value)) {
                $type = "serialized";
                $value = serialize($value);
            } else {
                $type = gettype($value);
            }
            $child = $xml->addChild($property->getName(), $value);
            $child->addAttribute("type", $type);
        } else {
            $child = $xml->addChild($match);
            $child->addAttribute("name", $property->getName());
            if (class_exists($match)) {
                getVariablesXML($match, $child);
            }
        }
    }
}