Pull to refresh

SimpleXML. Пример расширенного использования

Lumber room
Думаю многие пользователи уже знакомы с этим замечательным классом для обработки xml документов. В этой статье хочу привести несколько примеров использования, которых не нашел в официальной документации, но которые были бы полезны начинающим пользователям.

Простой пример использования


$xml = <<<EOF
<?xml version=«1.0» encoding=«UTF-8»?>
<recipe name=«хлеб» preptime=«5» cooktime=«180»>
<title>Простой хлеб</title>
<ingredient amount=«3» unit=«стакан»>Мука</ingredient>
<ingredient amount=«0.25» unit=«грамм»>Дрожжи</ingredient>
<ingredient amount=«1.5» unit=«стакан»>Тёплая вода</ingredient>
<ingredient amount=«1» unit=«чайная ложка»>Соль</ingredient>
<Instructions>
<step>Смешать все ингредиенты и тщательно замесить.</step>
<step>Закрыть тканью и оставить на один час в тёплом помещении.</step>
<step>Замесить ещё раз, положить на противень и поставить в духовку.</step>
</Instructions>
</recipe>

EOF;
$sx = new SimpleXMLElement( $xml );
var_dump( $sx );
* This source code was highlighted with Source Code Highlighter.

Этот код выведет в броузер следующий результат:
object(SimpleXMLElement)[1]
public '@attributes' =>
array
'name' => string 'хлеб' (length=8)
'preptime' => string '5' (length=1)
'cooktime' => string '180' (length=3)
public 'title' => string 'Простой хлеб' (length=23)
public 'ingredient' =>
array
0 => string 'Мука' (length=8)
1 => string 'Дрожжи' (length=12)
2 => string 'Тёплая вода' (length=21)
3 => string 'Соль' (length=8)
public 'Instructions' =>
object(SimpleXMLElement)[2]
public 'step' =>
array
0 => string 'Смешать все ингредиенты и тщательно замесить.' (length=84)
1 => string 'Закрыть тканью и оставить на один час в тёплом помещении.' (length=104)
2 => string 'Замесить ещё раз, положить на противень и поставить в духовку.' (length=113)

Как видите все достаточно прозрачно и никакая документация не нужна. Но что будет, если скормить этому классу:

Сложный пример


Это документ формата Microsoft Excel 2003 XML
<?xml version=«1.0» encoding=«UTF-8»?><?mso-application progid=«Excel.Sheet»?>
<Workbook xmlns=«urn:schemas-microsoft-com:office:spreadsheet» xmlns:xsiwww.w3.org/2001/XMLSchema-instance» xmlns:x=«urn:schemas-microsoft-com:office:excel» xmlns:x2schemas.microsoft.com/office/excel/2003/xml» xmlns:ss=«urn:schemas-microsoft-com:office:spreadsheet» xmlns:o=«urn:schemas-microsoft-com:office:office» xmlns:htmlwww.w3.org/TR/REC-html40» xmlns:c=«urn:schemas-microsoft-com:office:component:spreadsheet»>
<OfficeDocumentSettings xmlns=«urn:schemas-microsoft-com:office:office»>
<Colors>
<Color>
<Index>3</Index>
<RGB>#c0c0c0</RGB>
</Color>
<Color>
<Index>4</Index>
<RGB>#ff0000</RGB>
</Color>
</Colors>
</OfficeDocumentSettings>
<ExcelWorkbook xmlns=«urn:schemas-microsoft-com:office:excel»>
<WindowHeight>9000</WindowHeight>
<WindowWidth>13860</WindowWidth>
<WindowTopX>240</WindowTopX>
<WindowTopY>75</WindowTopY>
<ProtectStructure>False</ProtectStructure>
<ProtectWindows>False</ProtectWindows>
</ExcelWorkbook>
<Styles>
<Style ss:ID=«Default» ss:Name=«Default»/>
<Style ss:ID=«Result» ss:Name=«Result»>
<Font ss:Bold=«1» ss:Italic=«1» ss:Underline=«Single»/>
</Style>
<Style ss:ID=«Result2» ss:Name=«Result2»>
<Font ss:Bold=«1» ss:Italic=«1» ss:Underline=«Single»/>
<NumberFormat ss:Format=«Currency»/>
</Style>
<Style ss:ID=«Heading» ss:Name=«Heading»>
<Alignment ss:Horizontal=«Center»/>
<Font ss:Bold=«1» ss:Italic=«1» ss:Size=«16»/>
</Style>
<Style ss:ID=«Heading1» ss:Name=«Heading1»>
<Alignment ss:Horizontal=«Center» ss:Rotate=«90»/>
<Font ss:Bold=«1» ss:Italic=«1» ss:Size=«16»/>
</Style>
<Style ss:ID=«co1»/>
<Style ss:ID=«ta1»/>
</Styles>
<ss:Worksheet ss:Name=«Лист1»>
<Table ss:StyleID=«ta1»>
<Column ss:Span=«2» ss:Width=«64.2614»/>
<Row ss:Height=«12.1039»>
<Cell>
<Data ss:Type=«Number»>1</Data>
</Cell>
<Cell>
<Data ss:Type=«Number»>2</Data>
</Cell>
<Cell>
<Data ss:Type=«Number»>3</Data>
</Cell>
</Row>
<Row ss:Height=«12.1039»>
<Cell>
<Data ss:Type=«Number»>2</Data>
</Cell>
<Cell ss:Formula="=R[-1]C*RC1">
<Data ss:Type=«Number»>4</Data>
</Cell>
<Cell ss:Formula="=R[-1]C*RC1">
<Data ss:Type=«Number»>6</Data>
</Cell>
</Row>
<Row ss:Height=«12.1039»>
<Cell>
<Data ss:Type=«Number»>3</Data>
</Cell>
<Cell ss:Formula="=R[-2]C*RC1">
<Data ss:Type=«Number»>6</Data>
</Cell>
<Cell ss:Formula="=R[-2]C*RC1">
<Data ss:Type=«Number»>9</Data>
</Cell>
</Row>
</Table>
<x:WorksheetOptions/>
</ss:Worksheet>
<ss:Worksheet ss:Name=«Лист2»>
<Table ss:StyleID=«ta1»>
<Column ss:Width=«64.2614»/>
<Row ss:Height=«12.1039»>
<Cell ss:Index=«1»/>
</Row>
</Table>
<x:WorksheetOptions/>
</ss:Worksheet>
<ss:Worksheet ss:Name=«Лист3»>
<Table ss:StyleID=«ta1»>
<Column ss:Width=«64.2614»/>
<Row ss:Height=«12.1039»>
<Cell ss:Index=«1»/>
</Row>
</Table>
<x:WorksheetOptions/>
</ss:Worksheet>
</Workbook>
* This source code was highlighted with Source Code Highlighter.

Теперь наш код выведет не всю информацию о документе.
Не буду приводить полный вывод. Скажу лишь, что в выводе отсутствуют узлы ss:Worksheet

Получение узла ss:Worksheet
Способ первый. XPath

foreach ( $sx->xpath( '//ss:Worksheet' ) as $x ) print_r( $x );

Способ второй. NS

В документе определены следующие ns
xmlns=«urn:schemas-microsoft-com:office:spreadsheet»
xmlns:xsi=«www.w3.org/2001/XMLSchema-instance»
xmlns:x=«urn:schemas-microsoft-com:office:excel»
xmlns:x2=«schemas.microsoft.com/office/excel/2003/xml»
xmlns:ss=«urn:schemas-microsoft-com:office:spreadsheet»
xmlns:o=«urn:schemas-microsoft-com:office:office»
xmlns:html=«www.w3.org/TR/REC-html40»
xmlns:c=«urn:schemas-microsoft-com:office:component:spreadsheet»

Для доступа к Worksheet, который определен в urn:schemas-microsoft-com:office:spreadsheet потребуется следующий код
$sx->children('urn:schemas-microsoft-com:office:spreadsheet')->Worksheet

Для доступа к атрибутам также понадобится явно указывать ns.

PS. Некоторые сложности добавляет еще тот факт, что в SimpleXML большинство методов имеют итерационные свойства и не всегда можно использовать функции var_dump, print_r, etc…
PSPS: Возможно для Вас эта заметка будет бесполезной, но столкнувшись с проблемой перерыл достаточно много инфы, примеров не было…
Tags:phpsimplexmlxml
Hubs: Lumber room
Total votes 11: ↑8 and ↓3 +5
Views1.4K

Popular right now

Профессия iOS-разработчик
June 21, 202190,000 ₽SkillFactory
Факультет дизайна
June 21, 2021236,988 ₽GeekBrains
Профессия Аналитик данных
June 21, 202169,000 ₽SkillFactory
Data Analyst
June 21, 2021102,000 ₽SkillFactory

Top of the last 24 hours