您可以在.NET中执行以下操作:
XmlNode.SelectNodes(query, selectionNamespaces);
您可以使用javascript吗?
可以在msxml中完成吗?
尝试A :
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
给出一个包含XML片段的IXMLDOMNode:
<row>
<cell>a</cell>
<cell>b</cell>
<cell>c</cell>
</row>
我们可以使用IXMLDOMNode.selectNodes方法来选择子元素:
IXMLDOMNode row = //...xml above
IXMLDOMNodeList cells = row.selectNodes("/row/cell");
,这将返回 IXMLDOMNodeList :
<cell>a</cell>
<cell>b</cell>
<cell>c</cell>
那很好。
如果XML片段源自具有名称空间的文档,例如:
<row xmlns:ss="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<cell>a</cell>
<cell>b</cell>
<cell>c</cell>
</row>
相同的XPath查询不会有任何结果,因为元素row
和cell
不存在。它们在另一个名称空间中。
如果您拥有完整的 IXMLDOMDocument ,则可以使用 setProperty 方法来设置选择名称空间:
一种 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");
您会得到细胞:
<cell>a</cell>
<cell>b</cell>
<cell>c</cell>
IXMLDOMNode具有一个method to perform XPath queries:
selectNodes方法
将指定的模式匹配操作应用于此节点的上下文,并将匹配节点的列表作为
IXMLDOMNodeList
返回。HRESULT selectNodes( BSTR expression, IXMLDOMNodeList **resultList);
备注
有关将
selectNodes
方法与命名空间一起使用的更多信息,请参见setProperty Method主题。
但是在对DOM节点发出XPath查询时,无法指定选择命名空间。
使用XPath查询节点时如何指定名称空间?
.NET的 XmlNode 提供了 SelectNodes 方法,该方法提供接受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);
但是我不在C#中(我也不在Javascript中)。什么是本地msxml6等效项?
编辑:我不太喜欢Javascript (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.
答案 0 :(得分:0)
这在MSDN上得到了回答:
How To Specify Namespace when Querying the DOM with XPath
更新:
但是,请注意,在第二个示例XML中,将<row>
添加到{{1}时,XPath不会查询<cell>
和xmlns:peanut
元素}属性。这就是为什么找不到SelectionNamespaces
元素的原因。
要将它们正确放置到名称空间中,您必须:
将名称空间声明更改为使用<cell>
而不是xmlns=
:
xmlns:ss=
使用<row xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<cell>a</cell>
<cell>b</cell>
<cell>c</cell>
</row>
和<ss:row>
代替<ss:cell>
和<row>
:
<cell>
<ss:row xmlns:ss="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<ss:cell>a</cell>
<ss:cell>b</cell>
<ss:cell>c</cell>
</ss:row>
属性不会为您神奇地将元素放入命名空间,它仅指定XPath查询可以使用哪些命名空间。 XML本身必须根据需要将元素放入适当的名称空间中。
更新:
在新示例中,SelectionNamespaces
不起作用,因为XPath查询使用的是绝对路径,其中前导cells := row.selectNodes('/ss:row/ss:cell');
从文档根目录开始,并且存在XML文档顶部没有/
元素,只有<row>
元素。这就是<worksheet>
起作用的原因。
如果要执行从要查询的节点开始的XPath查询,请不要使用绝对路径,而应使用相对路径:
rows := doc.selectNodes('/ss:worksheet/ss:row');
或者简单地:
cells := row.selectNodes('ss:row/ss:cell');