在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. 浏览器安全可以防止网页向其他域发送请求,而不是为网页提供服务. 此限制称为相同源策略. 同一源策略可防止恶意站点读取另一个站点中 ...
随机推荐
- [RN] React Native 键盘管理 在Android TextInput遮盖,上移等问题解决办法
React Native 键盘管理 在Android TextInput遮盖,上移等问题解决办法 解决办法: 打开android工程,在AndroidManifest.xml中配置如下: <ac ...
- openjudge1.1
目录 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.1.10 1.1.1 描述 对于大部分编程语言来说,编写一个能够输出"H ...
- JAVA基础--MySQL(二)
数据库约束 1.基础限制 ① 单一表内字节量总和不能超过65535,null 占用一个字节空间 ② varchar存储255 以内字节占用一个字节表示长度,255以上自己则占用两个字节表示长度 ③ ...
- C语言中常见的图形打印总结
直角三角形(靠右直立) 示例实现代码如下: int main(){ int n; int i,j; cin >> n; if(n<= 0){ cout << " ...
- JS中的浅拷贝与深拷贝
浅拷贝与深拷贝的区别: 浅拷贝: 对基本类型和引用类型只进行值的拷贝,即,拷贝引用对象的时候,只对引用对象的内存地址拷贝,新旧引用属性指向同一个对象,修改任意一个都会影响所有引用当前对象的变量. 深拷 ...
- [SDOI2011]染色(信息学奥赛一本通 1563)(洛谷 2486)
Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“ ...
- ubuntu之路——day19.1 深度CNN的探究
1.经典的CNN LeNet-5 1998的CNN鼻祖 以前用的sigmoid和tanh 下图给的是relu和softmax AlexNet ImageNet2012的冠军 VGG-16 ImageN ...
- Segment fault 常见原因
[https://blog.csdn.net/qq_22238021/article/details/79872978] 本质原因在于:程序访问了非法的地址 1.引用空指针 2.野指针 3.访问越界 ...
- kafka安装运行(docker)
zookeeper参照https://www.cnblogs.com/wintersoft/p/11128484.html mkdir /opt/kafka -pvim /opt/kafka/Dock ...
- 【Linux】Linux环境变量的设置和查看
Linux的变量种类 按变量的生存周期来划分,Linux变量可分为两类: 1 永久的:需要修改配置文件,变量永久生效. 2 临时的:使用export命令声明即可,变量在关闭shell时失效. 设置变量 ...