В дополнение к существующему ответу Найджела Рена я подумал, что покажу, как выглядят те же самые циклы с SimpleXML.
Во-первых, обратите внимание, что вам не нужнопреобразовать XML в строку и обратно, если вы хотите по какой-либо причине переключаться между DOM и SimpleXML, вы можете использовать simplexml_import_dom , который просто меняет интерфейс:
$sxml = simplexml_import_dom($dom_xml);
Далее нам нужноTextFrame
элементов;мы могли бы либо пройти через структуру явно, как вы делали это раньше:
$textFrames = $sxml->Spread->TextFrame;
Или мы могли бы использовать XPath для поиска совпадающих имен тегов в нашем текущем узле (.
- текущий элемент, а //
означает «любой потомок»:
$textFrames = $sxml->xpath('.//TextFrame');
Первый даст вам SimpleXMLElement
объект, а второй массив, но в любом случае вы можете использовать foreach
для просмотра совпадений.
На этот раз мы определенно хотим, чтобы выражение XPath получало узлы PathPointType
, чтобы избежать всех вложенных циклов через уровни, которые нам не интересны:
foreach ( $textFrames as $frame ) {
$pathPointTypes = $frame->xpath('.//PathPointType');
foreach ( $pathPointTypes as $type ) {
echo $type['Anchor'] . PHP_EOL;
}
}
Обратите внимание, что вы неВам не нужно вызывать $type->attributes()
, если только вы не имеете дело с пространствами имен, все, что вам нужно для получения атрибута, это $node['AttributeName']
. Но имейте в виду, что атрибуты в SimpleXML являются объектами, поэтому вам часто нужно заставить их быть строкамис (string)$node['AttributeName']
.
Чтобы взять последний пример, у вас может быть что-то вроде этого:
$frames = [];
foreach ( $sxml->Spread->TextFrame as $frame ) {
$anchors = [];
$pathPointTypes = $frame->xpath('.//PathPointType');
foreach ( $pathPointTypes as $type ) {
$anchors[] = ['Anchor' => (string)$type['Anchor']];
}
$frames[] = $anchors;
}