我想知道是否有人知道如何从类列表中动态构建XML文件?
这些类包含公共变量,看起来像这样。
class node {
public $elementname;
}
我注意到某些类的名称与变量相同,在这种情况下,节点将是节点的子节点元素:
class data {
public $dataaset;
}
class dataset {
public $datasetint;
}
将是:
<data>
<dataset>datasetint</dataset>
</data>
也许是SimpleXML中的东西?
答案 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);
}
}
}
}