Операция в основном делает следующее:
Я добавил комментарии, так как это проще, чем пытаться добавить полное описание.
Но это в основном чтение дерева из файла, создание или переход к уровням при разборе каждой строки. Если в теге есть @
, то это означает создание атрибута ...
$file = file("a.txt", FILE_IGNORE_NEW_LINES);
// Extract root node to create new document
$firstLine = array_shift($file);
$xml = new SimpleXMLElement("<" . substr($firstLine,1) . " />");
foreach ( $file as $line ) {
// Set start insert point to root node
$xmlC = $xml;
$matches = [];
// Split into tag name and content parts
preg_match("/(.*?)\s+(.*)/", $line, $matches);
// Split levels of tag name apart
$tag = explode("/", substr($matches[1], 1));
// Root node is already there
$roottag = array_shift($tag);
// Check if adding an attribute to root node
$element = explode("@", $roottag);
if ( isset($element[1]) ) {
$xmlC->addAttribute($element[1], $matches[2]);
unset($matches[2]);
}
// For each level of tag
foreach ( $tag as $level ) {
$element = explode("@", $level);
// If tag is already set, then just move down a level
if ( isset($xmlC->{$element[0]}) ) {
$xmlC = $xmlC->{$element[0]};
}
// If not set then add a new element
else {
$xmlC = $xmlC->addChild($element[0]);
}
// If an attribute needs to be created
if ( isset($element[1]) ) {
$xmlC->addAttribute($element[1], $matches[2]);
unset($matches[2]);
}
}
// If there is a value, then add it to last node
if ( isset($matches[2]) ) {
$xmlC[0] = $matches[2];
}
}
echo $xml->asXML();
Немного триммерный цикл, который использует регулярные выражения, чтобы извлечь атрибут ...
foreach ( $file as $line ) {
// Set start insert point to root node
$xmlC = $xml;
$matches = [];
// Split into tag name, attribute and content parts
preg_match("/(.*?)(@.*?)?\s+(.*)/", $line, $matches);
// Split levels of tag name apart
$tag = explode("/", substr($matches[1], 1));
// Root node is already there
$roottag = array_shift($tag);
// For each level of tag
foreach ( $tag as $level ) {
// If tag is already set, then just move down a level
if ( isset($xmlC->{$level}) ) {
$xmlC = $xmlC->{$level};
}
// If not set then add a new element
else {
$xmlC = $xmlC->addChild($level);
}
}
// If there is a value, then add it to last node (either as an attribute or text
if ( !empty($matches[3]) ) {
if ( !empty($matches[2]) ) {
$xmlC->addAttribute(substr($matches[2],1), $matches[3]);
}
else {
$xmlC[0] = $matches[3];
}
}
}