Имеется XML-документ с неизвестной структурой (вложенностей может быть любое количество). Можно как-то обойти весь документ используя SimpleXML и получить нужные мне объекты, например, виды спорта?
p.s. В гугле нашёл статьи только для документов с известной структурой
Могу предложить проверенный способ парса XML
файлов любых строений, вывод данных будет в виде массива(если подойдёт)։
parseXml( $xml )
function parseXml( $xml ) {
$xml_parser = xml_parser_create();
xml_parse_into_struct( $xml_parser, $XML, $vals );
xml_parser_free( $xml_parser );
$_tmp = '';
foreach ( $vals as $xml_elem ) {
$x_tag = $xml_elem[ 'tag' ];
$x_level = $xml_elem[ 'level' ];
$x_type = $xml_elem[ 'type' ];
if ( $x_level != 1 && $x_type == 'close' ) {
if ( isset( $multi_key[ $x_tag ][ $x_level ] ) )
$multi_key[ $x_tag ][ $x_level ] = 1;
else
$multi_key[ $x_tag ][ $x_level ] = 0;
}
if ( $x_level != 1 && $x_type == 'complete' ) {
if ( $_tmp == $x_tag )
$multi_key[ $x_tag ][ $x_level ] = 1;
$_tmp = $x_tag;
}
}
foreach ( $vals as $xml_elem ) {
$x_tag = $xml_elem[ 'tag' ];
$x_level = $xml_elem[ 'level' ];
$x_type = $xml_elem[ 'type' ];
if ( $x_type == 'open' )
$level[ $x_level ] = $x_tag;
$start_level = 1;
$php_stmt = '$xml_array';
if ( $x_type == 'close' && $x_level != 1 )
$multi_key[ $x_tag ][ $x_level ]++;
while ( $start_level < $x_level ) {
$php_stmt .= '[$level[' . $start_level . ']]';
if ( isset( $multi_key[ $level[ $start_level ] ][ $start_level ] ) && $multi_key[ $level[ $start_level ] ][ $start_level ] )
$php_stmt .= '[' . ( $multi_key[ $level[ $start_level ] ][ $start_level ] - 1 ) . ']';
$start_level++;
}
$add = '';
if ( isset( $multi_key[ $x_tag ][ $x_level ] ) && $multi_key[ $x_tag ][ $x_level ] && ( $x_type == 'open' || $x_type == 'complete' ) ) {
if ( !isset( $multi_key2[ $x_tag ][ $x_level ] ) )
$multi_key2[ $x_tag ][ $x_level ] = 0;
else
$multi_key2[ $x_tag ][ $x_level ]++;
$add = '[' . $multi_key2[ $x_tag ][ $x_level ] . ']';
}
if ( isset( $xml_elem[ 'value' ] ) && trim( $xml_elem[ 'value' ] ) != '' && !array_key_exists( 'attributes', $xml_elem ) ) {
if ( $x_type == 'open' )
$php_stmt_main = $php_stmt . '[$x_type]' . $add . '[\'content\'] = $xml_elem[\'value\'];';
else
$php_stmt_main = $php_stmt . '[$x_tag]' . $add . ' = $xml_elem[\'value\'];';
eval( $php_stmt_main );
}
if ( array_key_exists( 'attributes', $xml_elem ) ) {
if ( isset( $xml_elem[ 'value' ] ) ) {
$php_stmt_main = $php_stmt . '[$x_tag]' . $add . '[\'content\'] = $xml_elem[\'value\'];';
eval( $php_stmt_main );
}
foreach ( $xml_elem[ 'attributes' ] as $key => $value ) {
$php_stmt_att = $php_stmt . '[$x_tag]' . $add . '[$key] = $value;';
eval( $php_stmt_att );
}
}
}
return $xml_array;
}
Очень простой способ парсинга XML-файла c неизвестной структурой. Создаём рекурсивную функцию для перебора $xml
:
public function xmlMap(&$result_array, SimpleXMLElement $xmlArray): void
{
foreach($xmlArray as $key => $node) {
if (!empty($node->children()->getName())) {
$object = $this->getObject($node);
if (!isset($result_array)) {
$result_array = array();
}
array_push($result_array, [$object, $node->children()->getName() => array()]);
$this->xmlMap($result_array[count($result_array)-1][$node->children()->getName()], $node);
}
}
}
Где:
$result_array - массив, в котором будут храниться полученные данные (передаётся по ссылке)
$xmlArray - собственно наша переменная $xml
getObject($node) - функция для создания объекта в зависимости от узла
public function getObject(SimpleXMLElement $node)
{
switch ($node->getName()) {
case XmlParser::NODE_SPORT:
$object = $this->getSportOrCountry($node, new Sport());
break;
case XmlParser::NODE_COUNTRY:
$object = $this->getSportOrCountry($node, new Country());
break;
case XmlParser::NODE_TOURNAMENT:
$object = $this->getTournament($node, new Tournament());
break;
case XmlParser::NODE_EVENT:
$object = $this->getEvent($node, new Event());
break;
case XmlParser::NODE_SCOPE:
$object = $this->getScope($node, new Scope());
break;
case XmlParser::NODE_MARKET:
$object = $this->getMarket($node, new Market());
break;
case XmlParser::NODE_OUTCOME:
$object = $this->getOutcome($node, new Outcome());
break;
default:
$object = null;
}
return $object;
}
Использование кода:
$xml = new SimpleXMLElement($this->xml_document);
$result_array = array();
$this->xmlMap($result_array, $xml);
var_dump($result_array);
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Виртуальный выделенный сервер (VDS) становится отличным выбором
Всем привет, в одной статье по рассылкам была рекомендация слать сразу несколько типов писем (html и txt), чтобы на разных устройствах, клиентах...
Сколько пишу на php ни разу isset не пригодилсяЯ проверял даже - если в массиве нет ключа, но ты пытаешься его получить то возвращает null без ошибок...