php - How to write xpath query with default namespace and attribute condition -
i have xml this:
<?xml version="1.0"?> <workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/tr/rec-html40"> <worksheet ss:name="name1"> </worksheet> <worksheet ss:name="name2"> else </worksheet> </workbook>
how query should turn me worksheet element ss:name attribute name1. because of default namespace have set first condition this:
//*[name()="worksheet"]
but don't know how add attribute condition...
------- update ------- because can't find solution here xml file (file generated excel):
<?xml version="1.0"?> <?mso-application progid="excel.sheet"?> <workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/tr/rec-html40"> <documentproperties xmlns="urn:schemas-microsoft-com:office:office"> <author>don diego</author> <lastauthor>don diego</lastauthor> <created>2013-04-18t07:20:33z</created> <lastsaved>2013-04-18t07:20:33z</lastsaved> <company>cei</company> <version>14</version> </documentproperties> <officedocumentsettings xmlns="urn:schemas-microsoft-com:office:office"> <allowpng/> </officedocumentsettings> <excelworkbook xmlns="urn:schemas-microsoft-com:office:excel"> <windowheight>7740</windowheight> <windowwidth>13395</windowwidth> <windowtopx>360</windowtopx> <windowtopy>30</windowtopy> <protectstructure>false</protectstructure> <protectwindows>false</protectwindows> </excelworkbook> <styles> <style ss:id="default" ss:name="normal"> <alignment ss:vertical="bottom"/> <borders/> <font ss:fontname="calibri" x:charset="238" x:family="swiss" ss:size="11" ss:color="#000000"/> <interior/> <numberformat/> <protection/> </style> </styles> <worksheet ss:name="sheet1"> <table ss:expandedcolumncount="1" ss:expandedrowcount="1" x:fullcolumns="1" x:fullrows="1" ss:defaultrowheight="15"/> <worksheetoptions xmlns="urn:schemas-microsoft-com:office:excel"> <pagesetup> <header x:margin="0.3"/> <footer x:margin="0.3"/> <pagemargins x:bottom="0.75" x:left="0.7" x:right="0.7" x:top="0.75"/> </pagesetup> <selected/> <panes> <pane> <number>3</number> <activecol>1</activecol> </pane> </panes> <protectobjects/> <protectscenarios/> </worksheetoptions> </worksheet> <worksheet ss:name="sheet2"> <table ss:expandedcolumncount="1" ss:expandedrowcount="1" x:fullcolumns="1" x:fullrows="1" ss:defaultrowheight="15"/> <worksheetoptions xmlns="urn:schemas-microsoft-com:office:excel"> <pagesetup> <header x:margin="0.3"/> <footer x:margin="0.3"/> <pagemargins x:bottom="0.75" x:left="0.7" x:right="0.7" x:top="0.75"/> </pagesetup> <selected/> <panes> <pane> <number>3</number> <activecol>1</activecol> </pane> </panes> <protectobjects/> <protectscenarios/> </worksheetoptions> </worksheet> <worksheet ss:name="sheet3"> <table ss:expandedcolumncount="1" ss:expandedrowcount="1" x:fullcolumns="1" x:fullrows="1" ss:defaultrowheight="15"/> <worksheetoptions xmlns="urn:schemas-microsoft-com:office:excel"> <pagesetup> <header x:margin="0.3"/> <footer x:margin="0.3"/> <pagemargins x:bottom="0.75" x:left="0.7" x:right="0.7" x:top="0.75"/> </pagesetup> <selected/> <panes> <pane> <number>3</number> <activecol>1</activecol> </pane> </panes> <protectobjects/> <protectscenarios/> </worksheetoptions> </worksheet> </workbook>
i want worksheet element attribute 'sheet1' xpath. , here i've got:
$uri = $this->doc->getdocnamespaces()['']; //$this->doc obiect of simplexmlelement class $this->doc->registerxpathnamespace('default', $uri); //'urn:schemas-microsoft-com:office:spreadsheet' $current_worksheet = $this->doc->xpath('/*/default:worksheet[@ss:name = "sheet1"]'); die(var_dump($current_worksheet));//empty array :(
for $current_worksheet empty array :( looks default namespace same ss namespace (same urn)?
/*/ss:worksheet[@ss:name = "name1"]
you have got 2 options here. first start 1 think more correct. makes use of namespace. have working need register namespace-prefix according uri, here 2 namespaces:
prefix: default uri : urn:schemas-microsoft-com:office:spreadsheet prefix: ss uri : urn:schemas-microsoft-com:office:spreadsheet
you can query:
/*/default:worksheet[@ss:name = "name1"]
the second variant same xpath query, ignoring namespace of non-default namespaces. works local-name()
, more complex:
/*/*[local-name()="worksheet"][@*[local-name()="name" , . = "name1"]]
as can see, first variant preferable because more readable. more distinct names each concrete element , not local-name.
here short example how can register xml namespace prefix can used xpath. necessary because default namespace non-empty:
$xml = simplexml_load_string($string); $uri = $xml->getdocnamespaces()['']; $xml->registerxpathnamespace('default', $uri); $result = $xml->xpath('/*/default:worksheet[@ss:name = "name1"]'); echo trim($result[0]), "\n"; #
online demo - worth remember: each element, each attribute can have own namespace. attribute namespaces not elements namespace automatically (only document default ones).
Comments
Post a Comment