短版
尝试
IXMLDOMNode.selectNodes(query); //no namespaces option
尝试B
IXMLDOMNode.ownerDocument.setProperty("SelectionNamespaces", selectionNamespaces);
IXMLDOMNode.selectNodes(query); //doesn't work
尝试C
IXMLDOMDocument3 doc;
doc.setProperty("SelectionNamespaces", selectionNamespaces);
IXMLDOMNodeList list = doc.selectNodes(...)[0].selectNodes(query); //doesn't work
长版
IXMLDOMNode
<row>
<cell>a</cell>
<cell>b</cell>
<cell>c</cell>
</row>
我们可以使用
IXMLDOMNode.selectNodes
选择子元素的方法:
IXMLDOMNode row = //...xml above
IXMLDOMNodeList cells = row.selectNodes("/row/cell");
:
-
<cell>a</cell>
-
<cell>b</cell>
-
<cell>c</cell>
但是名称空间破坏了它
<row xmlns:ss="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<cell>a</cell>
<cell>b</cell>
<cell>c</cell>
</row>
同一个XPath查询不会有任何结果,因为元素
row
和
cell
不存在;它们在另一个命名空间中。
使用默认命名空间查询文档
如果你有一个完整的
IXMLDOMDocument
,您可以使用
方法来设置
:
一
b
c
给
-
以前
xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
-
之后
:
xmlns:peanut="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
然后你呢
可以
查询它:
IXMLDOMDocument3 doc = //...document xml above
doc.setProperty("SelectionNamespaces", "xmlns:peanut="http://schemas.openxmlformats.org/spreadsheetml/2006/main");
IXMLDOMNodeList cells = doc.selectNodes("/peanut:row/peanut:cell");
你得到了你的手机:
-
<单元格>a</cell>
-
<
-
<单元格>c</cell>
但这对节点不起作用
method to perform XPath queries:
selectNodes方法
将指定的模式匹配操作应用于此节点的上下文,并将匹配节点列表返回为
IXMLDOMNodeList
.
HRESULT selectNodes(
BSTR expression,
IXMLDOMNodeList **resultList);
selectNodes
方法,请参见
setProperty Method
但是在对DOM节点发出XPath查询时,无法指定选择名称空间。
使用XPath查询节点时,如何指定命名空间?
.NET的
提供
XmlNamespaceManager
参数:
XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
ns.AddNamespace("peanut", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
cells = row.SelectNodes("/peanut:row/peanut:cell", ns);
编辑
(
jsFiddle
)
program Project3;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, msxml, ActiveX;
procedure Main;
var
s: string;
doc: DOMDocument60;
rows: IXMLDOMNodeList;
row: IXMLDOMElement;
cells: IXMLDOMNodeList;
begin
s :=
'<?xml version="1.0" encoding="UTF-16" standalone="yes"?>'+#13#10+
'<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">'+#13#10+
'<row>'+#13#10+
' <cell>a</cell>'+#13#10+
' <cell>b</cell>'+#13#10+
' <cell>c</cell>'+#13#10+
'</row>'+#13#10+
'</worksheet>';
doc := CoDOMDocument60.Create;
doc.loadXML(s);
if doc.parseError.errorCode <> 0 then
raise Exception.CreateFmt('Parse error: %s', [doc.parseError.reason]);
doc.setProperty('SelectionNamespaces', 'xmlns:ss="http://schemas.openxmlformats.org/spreadsheetml/2006/main"');
//Query for all the rows
rows := doc.selectNodes('/ss:worksheet/ss:row');
if rows.length = 0 then
raise Exception.Create('Could not find any rows');
//Do stuff with the first row
row := rows[0] as IXMLDOMElement;
//Get the cells in the row
(row.ownerDocument as IXMLDOMDocument3).setProperty('SelectionNamespaces', 'xmlns:ss="http://schemas.openxmlformats.org/spreadsheetml/2006/main"');
cells := row.selectNodes('/ss:row/ss:cell');
if cells.length <> 3 then
raise Exception.CreateFmt('Did not find 3 cells in the first row (%d)', [cells.length]);
end;
begin
try
CoInitialize(nil);
Main;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.