2012-10-09 100 views
1

我想知道是否有人知道如何從類列表中動態地構建XML文件?從PHP中的類構建XML文件

這些類包含公共變量,看起來像這樣。

class node { 
    public $elementname; 
} 

我也注意到,一些類被命名爲相同的變量,在這種情況下,該節點將是一個節點的子節點元素:

class data { 
    public $dataaset; 
} 

class dataset { 
    public $datasetint; 
} 

是:

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

也許在SimpleXML什麼的?

+0

'$類dataset'?不要這樣想。 –

+0

固定,對不起回合 – bear

回答

7

我能想到的連接2個或更多不相關類的唯一解決方案是使用Annotations

批註默認情況下不會在PHP,但目前在RFC (Request for Comments: Class Metadata)支持,但支持或拒絕,你可以使用ReflectionClass & 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); 
      } 
     } 
    } 
} 
+1

正是我的想法。但是,當我還在形成想法時,你提供了工作代碼:)令人印象深刻的 – Vafliik

+1

@Vafliik相信它可以改進...讓我試一試 – Baba

+0

@Vafliik我讓它遞歸...無限級 – Baba