我有这样的xml:
<?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">
something
</Worksheet>
<Worksheet ss:Name="Name2">
something else
</Worksheet>
</Workbook>
查询应该如何使我的工作表元素变成ss:Name属性Name1。由于默认命名空间,我必须像这样设置第一个条件:
//*[name()="Worksheet"]
但我不知道如何添加属性条件...
-------更新------- 因为我在这里找不到解决方案所有的xml文件(由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>
我想通过XPath获取带有属性“Sheet1”的Worksheet元素。 这就是我所拥有的:
$uri = $this->doc->getDocNamespaces()['']; //$this->doc is 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 :(
现在$ current_worksheet是一个空数组:(看起来默认命名空间与ss命名空间相同(同一个urn)?
答案 0 :(得分:1)
/*/ss:Worksheet[@ss:Name = "Name1"]
这里有两个选择。首先,我从我认为更正确的那个开始。它使用命名空间。要使它工作,您需要使用相应的URI注册namespace-prefix,这里有两个名称空间:
Prefix: default
URI : urn:schemas-microsoft-com:office:spreadsheet
Prefix: ss
URI : urn:schemas-microsoft-com:office:spreadsheet
然后你可以查询:
/*/default:Worksheet[@ss:Name = "Name1"]
第二个变体执行完全相同的xpath查询,但忽略所有非默认命名空间的命名空间。这与local-name()
一起使用并且更复杂:
/*/*[local-name()="Worksheet"][@*[local-name()="Name" and . = "Name1"]]
如您所见,第一个变体更可取,因为它更具可读性。它也更加独特,因为它命名每个具体元素,而不仅仅是本地名称。
这是一个简短的示例,您可以如何注册XML名称空间前缀,以便它可以与xpath一起使用。这是必要的,因为默认命名空间是非空的:
$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"; # something
Online Demo - 值得记住:与每个元素一样,每个属性也可以拥有自己的命名空间。属性名称空间不是自动的元素名称空间(只有文档默认名称空间)。
答案 1 :(得分:0)
更像这样的事情:
选择“名称”元素,其中“名称”属性值为“名称1 ”。
//Worksheet[@ss:Name='Name1']
答案 2 :(得分:0)
/x:Workbook/x:Worksheet[@ss:Name='Name1']
命名空间前缀“x”和“ss”在调用应用程序中绑定到相应的命名空间URI,使用您用于运行XPath的任何API。
答案 3 :(得分:0)
好的,我找到了为什么hakre的xpath对我不起作用的原因,我不知道为什么但这段代码
$xml = <<<XML
<?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">
</Workbook>
XML;
$el = new SimpleXmlElement($xml);
$child = $el->addChild('Worksheet');
$child->addAttribute('xmlns:ss:Name', 'Sheet1');
$result = $el->xpath("ss:Worksheet[@ss:Name='Sheet1']");
没用。我必须创建新的SimpleXMLElement才能使它工作,如下所示:
$xml = <<<XML
<?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">
</Workbook>
XML;
$el = new SimpleXmlElement($xml);
$child = $el->addChild('Worksheet');
$child->addAttribute('xmlns:ss:Name', 'Sheet1');
$el = new SimpleXMLElement($el->asXML()); //refreshing of SimpleXMLElement
$result = $el->xpath("ss:Worksheet[@ss:Name='Sheet1']"); //now it work like a charm
感谢您的帮助