Pull to refresh

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

Reading time8 min
Views3.5K
Думаю многие пользователи уже знакомы с этим замечательным классом для обработки 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:
Hubs:
Total votes 11: ↑8 and ↓3+5
Comments6

Articles