TXMLDocument的类让你来操作VCL和FireMonkey应用程序的XML文件,但这个类没有实现直接的方式来调用XPath的相关方法(selectNode的selectNodes),所以你必须编写一组辅助函数来调用这些方法。

通常你可以写这样的东西

function selectSingleNode(ADOMDocument: IDOMDocument; const nodePath: WideString): IDOMNode;
var
LDomNodeSelect : IDomNodeSelect;
begin
if not Assigned(ADOMDocument) or not Supports(ADOMDocument.documentElement, IDomNodeSelect, LDomNodeSelect) then
Exit;
//or just LDomNodeSelect:= (ADOMDocument.documentElement as IDOMNodeSelect);
Result:=LDomNodeSelect.selectNode(nodePath);
end;
function SelectNodes(ADOMDocument: IDOMDocument; const nodePath: WideString): IDOMNodeList;
var
LDomNodeSelect : IDomNodeSelect;
begin
if not Assigned(ADOMDocument) or not Supports(ADOMDocument.documentElement, IDomNodeSelect, LDomNodeSelect) then
Exit;
//or just LDomNodeSelect:= (ADOMDocument.documentElement as IDOMNodeSelect);
Result:=LDomNodeSelect.selectNodes(nodePath);
end;

并这样使用:

var
XmlDoc: IXMLDocument;
LNode : IDOMNode;
i : Integer;
begin
XmlDoc := TXMLDocument.Create(nil);
XmlDoc.Active := True;
XmlDoc.Options := XmlDoc.Options + [doNodeAutoIndent];
XmlDoc.Version := '1.0';
...
...
LNode:=selectSingleNode(XmlDoc.DOMDocument,XPathExpr);

上面的代码在Windows下使用MSXML提供程序作为默认DOM供应商可以正常工作,但在必须在OSX和Windows中运行的FireMonkey应用程序中,必须将默认DOM供应商设置为ADOM(OpenXML)。

DefaultDOMVendor := OpenXML4Factory.Description;

现在,如果您尝试在ADOM供应商下使用上述功能(selectSingleNode,SelectNodes),您将获得一个非常好的例外

EOleException Catastrophic failure 8000FFFF

这个问题的根目录是Tox4DOMNode.selectNodeTox4DOMNode.selectNodes这些方法的实现,请检查下一个代码。

function Tox4DOMNode.selectNode(const nodePath: WideString): IDOMNode;
var
xpath: TXpathExpression;
xdomText: TDomText;
begin
Result := nil;
if not Assigned(WrapperDocument) or not Assigned(WrapperDocument.WrapperDOMImpl) then
Exit; xpath := WrapperDocument.WrapperDOMImpl.FXpath; //here the xpath is set with a nil value because the FXpath was no initialized
xpath.ContextNode := NativeNode; //Here the App crash because xpath is nil

FXpath字段在Tox4DOMImplementation.InitParserAgent方法中初始化,该方法永远不会调用您使用Tox4DOMImplementation.loadFromStreamTox4DOMImplementation.loadxml方法的方法。因此,要解决此问题,必须在调用selectNode和selectNodes方法之前调用Tox4DOMImplementation.InitParserAgent函数。

function selectSingleNode(ADOMDocument: IDOMDocument; const nodePath: WideString): IDOMNode;
var
LDomNodeSelect : IDomNodeSelect;
begin
if not Assigned(ADOMDocument) or not Supports(ADOMDocument.documentElement, IDomNodeSelect, LDomNodeSelect) then
Exit;
//or just LDomNodeSelect:= (ADOMDocument.documentElement as IDOMNodeSelect);
if (DefaultDOMVendor = OpenXML4Factory.Description) then
Tox4DOMNode(LDomNodeSelect).WrapperDocument.WrapperDOMImpl.InitParserAgent;
Result:=LDomNodeSelect.selectNode(nodePath);
end;
function SelectNodes(ADOMDocument: IDOMDocument; const nodePath: WideString): IDOMNodeList;
var
LDomNodeSelect : IDomNodeSelect;
begin
if not Assigned(ADOMDocument) or not Supports(ADOMDocument.documentElement, IDomNodeSelect, LDomNodeSelect) then
Exit;
//or just LDomNodeSelect:= (ADOMDocument.documentElement as IDOMNodeSelect);
if (DefaultDOMVendor = OpenXML4Factory.Description) then
Tox4DOMNode(LDomNodeSelect).WrapperDocument.WrapperDOMImpl.InitParserAgent;
Result:=LDomNodeSelect.selectNodes(nodePath);
end;

现在通过这些更改,您将能够使用ADOM供应商评估VCL和FireMonkey应用程序中的XPath表达式。

这是在Windows和OSX (Delphi 10.3.2 Rio)中测试的演示控制台应用程序:

 // reference  https://theroadtodelphi.wordpress.com/2013/05/29/enabling-xpath-selectnode-selectnodes-methods-in-vcl-and-firemonkey-apps/

 {$APPTYPE CONSOLE}
uses
{$IFDEF MSWINDOWS}
System.Win.ComObj,
Winapi.ActiveX,
{$ENDIF}
System.SysUtils,
Xml.XMLIntf,
Xml.adomxmldom,
Xml.XMLDom,
Xml.XMLDoc; function selectSingleNode(ADOMDocument: IDOMDocument; const nodePath: WideString): IDOMNode;
var
LDomNodeSelect: IDomNodeSelect;
begin
if not Assigned(ADOMDocument) or not Supports(ADOMDocument.documentElement, IDomNodeSelect, LDomNodeSelect) then
Exit;
// or just LDomNodeSelect:= (ADOMDocument.documentElement as IDOMNodeSelect);
if (DefaultDOMVendor = OpenXML4Factory.Description) then
Tox4DOMNode(LDomNodeSelect).WrapperDocument.WrapperDOMImpl.InitParserAgent;
Result := LDomNodeSelect.selectNode(nodePath);
end; function SelectNodes(ADOMDocument: IDOMDocument; const nodePath: WideString): IDOMNodeList;
var
LDomNodeSelect: IDomNodeSelect;
begin
if not Assigned(ADOMDocument) or not Supports(ADOMDocument.documentElement, IDomNodeSelect, LDomNodeSelect) then
Exit;
// or just LDomNodeSelect:= (ADOMDocument.documentElement as IDOMNodeSelect);
if (DefaultDOMVendor = OpenXML4Factory.Description) then
Tox4DOMNode(LDomNodeSelect).WrapperDocument.WrapperDOMImpl.InitParserAgent;
Result := LDomNodeSelect.SelectNodes(nodePath);
end; procedure TestXPath;
var
XMLDoc: IXMLDocument;
Root, Book, Author, Publisher: IXMLNode;
LNodeList: IDOMNodeList;
LNode: IDOMNode;
i: Integer;
begin
XMLDoc := TXMLDocument.Create(nil);
XMLDoc.Active := True;
XMLDoc.Options := XMLDoc.Options + [doNodeAutoIndent];
XMLDoc.Version := '1.0'; Root := XMLDoc.CreateNode('BookStore');
Root.Attributes['url'] := 'http://www.amazon.com';
XMLDoc.documentElement := Root; Book := XMLDoc.CreateNode('Book');
Book.Attributes['Name'] := 'Steve Jobs';
Author := XMLDoc.CreateNode('Author');
Author.Text := 'Walter Isaacson';
Publisher := XMLDoc.CreateNode('Publisher');
Publisher.Text := 'Simon Schuster (October 24, 2011)';
Root.ChildNodes.Add(Book);
Book.ChildNodes.Add(Author);
Book.ChildNodes.Add(Publisher); Book := XMLDoc.CreateNode('Book');
Book.Attributes['Name'] := 'Clean Code: A Handbook of Agile Software Craftsmanship';
Author := XMLDoc.CreateNode('Author');
Author.Text := 'Robert C. Martin';
Publisher := XMLDoc.CreateNode('Publisher');
Publisher.Text := 'Prentice Hall; 1 edition (August 11, 2008)';
Root.ChildNodes.Add(Book);
Book.ChildNodes.Add(Author);
Book.ChildNodes.Add(Publisher); Book := XMLDoc.CreateNode('Book');
Book.Attributes['Name'] := 'Paradox Lost';
Author := XMLDoc.CreateNode('Author');
Author.Text := 'Kress, Peter';
Publisher := XMLDoc.CreateNode('Publisher');
Publisher.Text := 'Prentice Hall; 1 edition (February 2, 2000)';
Root.ChildNodes.Add(Book);
Book.ChildNodes.Add(Author);
Book.ChildNodes.Add(Publisher); Writeln(XMLDoc.Xml.Text); Writeln('selectSingleNode');
LNode := selectSingleNode(XMLDoc.DOMDocument, '/BookStore/Book[2]/Author["Robert C. Martin"]');
if LNode <> nil then
Writeln(LNode.firstChild.nodeValue); Writeln; Writeln('SelectNodes');
LNodeList := SelectNodes(XMLDoc.DOMDocument, '//BookStore/Book/Author');
if LNodeList <> nil then
for i := to LNodeList.length - do
Writeln(LNodeList[i].firstChild.nodeValue);
end; begin
try
ReportMemoryLeaksOnShutdown := True;
DefaultDOMVendor := OpenXML4Factory.Description;
{$IFDEF MSWINDOWS}CoInitialize(nil); {$ENDIF}
try
TestXPath;
finally
{$IFDEF MSWINDOWS}CoUninitialize; {$ENDIF}
end;
except
{$IFDEF MSWINDOWS}
on E: EOleException do
Writeln(Format('EOleException %s %x', [E.Message, E.ErrorCode]));
{$ENDIF}
on E: Exception do
Writeln(E.Classname, ':', E.Message);
end;
Writeln;
Writeln('Press Enter to exit');
Readln; end.

在Vcl和FireMonkey应用程序中启用TXMLDocument 的XPath(selectNode,selectNodes)方法的更多相关文章

  1. linux c程序中获取shell脚本输出的实现方法

    linux c程序中获取shell脚本输出的实现方法 1. 前言Unix界有一句名言:“一行shell脚本胜过万行C程序”,虽然这句话有些夸张,但不可否认的是,借助脚本确实能够极大的简化一些编程工作. ...

  2. VC++ 在两个程序中 传送字符串等常量值的方法:使用了 WM_COPYDATA 消息(转载)

    转载:http://www.cnblogs.com/renyuan/p/5037536.html VC++ 在两个程序中 传递字符串等常量值的方法:使用了 WM_COPYDATA 消息的 消息作用:  ...

  3. 在Windows程序中启用console输出-2016.01.04

    在某些时候,我们可能需要在Win32窗口应用程序中打开控制台窗口,打印一些消息,或者作为当前程序的另外一个人机交互界面,或者为了帮助调试程序.为了达到这种效果,需要了解函数AllocConsole和C ...

  4. ASP.NET MVC3 Web应用程序中启用GZip压缩示例

    http://www.mzwu.com/article.asp?id=3284 自定义一个筛选器,继承于GZipAttribute: using System;using System.IO.Comp ...

  5. VC++ 在两个程序中 传递字符串等常量值的方法:使用了 WM_COPYDATA 消息的

    消息作用:    在进程间共享数据(内部通过创建内存映射文件) 消息介绍:需要用到的数据结构/类型:typedef struct tagCOPYDATASTRUCT {    ULONG_PTR dw ...

  6. 关于微信小程序中的样式使用变量值的方法

    在开发过程中,通常碰到样式非固定的情况,这时候就要使用变量来规定样式,例如,一个view的宽度需要使用变量: 1. 在wxss中,定义变量:width:var(--width--); 2. 在js中, ...

  7. 在程序中通过Process启动外部exe的方法及注意事项

    启动外部进程的方法: /// <summary> /// 启动外部进程 /// </summary> /// <param name="path"&g ...

  8. 在ASP.NET应用程序中使用身份模拟(Impersonation)

    摘要   缺省情况下,ASP.NET应用程序以本机的ASPNET帐号运行,该帐号属于普通用户组,权限受到一定的限制,以保障ASP.NET应用程序运行的安全.但是有时需要某个ASP.NET应用程序或者程 ...

  9. 在 ASP.NET Core 中启用跨域请求(CORS)

    本文介绍如何在 ASP.NET Core 的应用程序中启用 CORS. 浏览器安全可以防止网页向其他域发送请求,而不是为网页提供服务. 此限制称为相同源策略. 同一源策略可防止恶意站点读取另一个站点中 ...

随机推荐

  1. 在WinDbg中显示和搜索std::map内容

    我们希望在WinDbg中自动显示.搜索和过滤std::map对象.std::vectors的脚本相对简单,因为vectors中数据的平面结构:map是更复杂的野兽.具体地说,Visual C++ ST ...

  2. 0.学习springmvc补充

    一.我的截图中的程序错误: 其中的路径写的是:"/user/testString" 这样写会错误当tomcat中配置的根目录为"/"或” “成功,但当配置为”x ...

  3. bzoj4066: 简单题 K-Dtree

    bzoj4066: 简单题 链接 bzoj 思路 强制在线.k-dtree. 卡常啊.空间开1e6就T了. 代码 #include <bits/stdc++.h> #define my_m ...

  4. JMeter压测工具安装及使用总结

    一.安装 进入apache官网https://www.apache.org/dist/jmeter/binaries下载Windows版本JMeter: 二.配置环境变量 下载之后解压,配置环境变量 ...

  5. Review of Semantic Segmentation with Deep Learning

    In this post, I review the literature on semantic segmentation. Most research on semantic segmentati ...

  6. 一条简单的 SQL 执行超过 1000ms,纳尼?

    阅读本文大概需要 2.8 分钟. MySQL 对我说 “Too young, too naive!" ▌大概过程 在测试环境 Docker 容器中,在跨进程调用服务的时候,A 应用通过 Du ...

  7. Better intuition for information theory

    Better intuition for information theory 2019-12-01 21:21:33 Source: https://www.blackhc.net/blog/201 ...

  8. 工具系列 | Docker基本概念

    1.什么是docker? Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化. ...

  9. LB中使用到的一致性Hash算法的简单实现

    1.类的Diagram 2.代码实现 2.1.Node类,每个Node代表集群里面的一个节点或者具体说是某一台物理机器: package consistencyhash; import lombok. ...

  10. Supervisor进程守护工具的使用

    Supervisor是一个 Python 开发的 client/server 系统,可以管理和监控类 UNIX 操作系统上面的进程. 官网:http://supervisord.org/      G ...