在Vcl和FireMonkey应用程序中启用TXMLDocument 的XPath(selectNode,selectNodes)方法
该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.selectNode和Tox4DOMNode.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.loadFromStream或Tox4DOMImplementation.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)方法的更多相关文章
- linux c程序中获取shell脚本输出的实现方法
linux c程序中获取shell脚本输出的实现方法 1. 前言Unix界有一句名言:“一行shell脚本胜过万行C程序”,虽然这句话有些夸张,但不可否认的是,借助脚本确实能够极大的简化一些编程工作. ...
- VC++ 在两个程序中 传送字符串等常量值的方法:使用了 WM_COPYDATA 消息(转载)
转载:http://www.cnblogs.com/renyuan/p/5037536.html VC++ 在两个程序中 传递字符串等常量值的方法:使用了 WM_COPYDATA 消息的 消息作用: ...
- 在Windows程序中启用console输出-2016.01.04
在某些时候,我们可能需要在Win32窗口应用程序中打开控制台窗口,打印一些消息,或者作为当前程序的另外一个人机交互界面,或者为了帮助调试程序.为了达到这种效果,需要了解函数AllocConsole和C ...
- ASP.NET MVC3 Web应用程序中启用GZip压缩示例
http://www.mzwu.com/article.asp?id=3284 自定义一个筛选器,继承于GZipAttribute: using System;using System.IO.Comp ...
- VC++ 在两个程序中 传递字符串等常量值的方法:使用了 WM_COPYDATA 消息的
消息作用: 在进程间共享数据(内部通过创建内存映射文件) 消息介绍:需要用到的数据结构/类型:typedef struct tagCOPYDATASTRUCT { ULONG_PTR dw ...
- 关于微信小程序中的样式使用变量值的方法
在开发过程中,通常碰到样式非固定的情况,这时候就要使用变量来规定样式,例如,一个view的宽度需要使用变量: 1. 在wxss中,定义变量:width:var(--width--); 2. 在js中, ...
- 在程序中通过Process启动外部exe的方法及注意事项
启动外部进程的方法: /// <summary> /// 启动外部进程 /// </summary> /// <param name="path"&g ...
- 在ASP.NET应用程序中使用身份模拟(Impersonation)
摘要 缺省情况下,ASP.NET应用程序以本机的ASPNET帐号运行,该帐号属于普通用户组,权限受到一定的限制,以保障ASP.NET应用程序运行的安全.但是有时需要某个ASP.NET应用程序或者程 ...
- 在 ASP.NET Core 中启用跨域请求(CORS)
本文介绍如何在 ASP.NET Core 的应用程序中启用 CORS. 浏览器安全可以防止网页向其他域发送请求,而不是为网页提供服务. 此限制称为相同源策略. 同一源策略可防止恶意站点读取另一个站点中 ...
随机推荐
- Vuejs基本使用
一.简单使用 ①首先需要实例化vue:new 出来,注意Vue大小写 ②通过el绑定元素:el 选项的作用就是告诉 Vue 管理模板的入口节点(不要绑定body和html) ③data:是响应式数据, ...
- ex3
#include <stdio.h> int main() { char ch; printf("please input:\n"); scanf("%c&q ...
- SpringBoot之文件上传体积过大问题(解决方案)
错误信息如下(关键): org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException: the re ...
- java并发编程(四) 线程池 & 任务执行、终止源码分析
参考文档 线程池任务执行全过程:https://blog.csdn.net/wojiaolinaaa/article/details/51345789 线程池中断:https://www.cnblog ...
- Kafka(三)High Availability 高可用
参考文档: http://www.jasongj.com/2015/04/24/KafkaColumn2/#ACK%E5%89%8D%E9%9C%80%E8%A6%81%E4%BF%9D%E8%AF% ...
- [Gamma阶段]第三次Scrum Meeting
Scrum Meeting博客目录 [Gamma阶段]第三次Scrum Meeting 基本信息 名称 时间 地点 时长 第三次Scrum Meeting 19/05/29 大运村寝室6楼 30min ...
- tp使用ajaxReturn返回二维数组格式的字符串,前台如何获取非乱码
参考: https://www.cnblogs.com/jiqing9006/p/5000849.html https://blog.csdn.net/zengxiangxuan123456/arti ...
- javascript常用方法 - String
// 1.长字符串 // 1.1 let longString1 = "This is a very long string which needs " + "to wr ...
- 查看当前页面的jsp文件【我】
方法一:可以通过看html类型的请求 方法二:对于有些嵌入的子页面,也可以通过,鼠标右键——此框架——查看框架源代码的方式,直接找到对应的jsp 直接就可以看到对应的jsp:
- Qt 一张图片显示在其他组件之上
图片放在QLabel上,注意设置QLable一些属性 QImage img("test.png"); img = img.scaledToWidth(,Qt::SmoothTran ...