在IDOMNode和IXMLNode之间有些困惑。我想要将一个文档中的子元素追加到一个使用XPath选择的节点中。
我尝试了以下方法:
尝试1:
我使用IDOMNodeSelect.selectNodes(expression);
从XPath结果节点N:IDOMNode中获取节点。如果我使用以下代码将其转换回IXMLNode:
intfDocAccess : IXmlDocumentAccess;
doc: TXMLDocument;
...
if Supports( N.OwnerDocument, IXmlDocumentAccess, intfDocAccess) then
doc := intfDocAccess.DocumentObject
else
doc := nil;
NodeAsIXMLNode := TXmlNode.Create( N, nil, doc );
如果向一个节点添加子节点会抛出“访问冲突”的错误,可能是因为NodeAsIXMLNode不在原始文档中,而只是为了类型兼容性而创建的副本...
尝试直接向XPath结果节点添加子节点:
XMLNode := XmlDoc.CreateElement( 'tag', '' );
N.appendChild( XMLNode as IDOMNode );
它抛出“接口不支持”的错误。我有一种感觉,xpath结果IDOMNode节点也不是原始IXMLDocument的成员,只是一些结果副本。这只是猜测。
那么我该如何使用xpath选择一个节点,然后将子元素节点附加到它上面呢?这样我的原始IXMLDocument就会得到更新。
更新:遍历整个xml文档树,并将IXMLNode的DOMNode与XPath结果DOMNode进行比较也不起作用——XPath结果节点不包含在原始文档中。尝试了msxml、adom和omnixml实现/XE7/。
更新2:设法使用第一种方法,只需替换即可。
doc := nil;
使用
doc := _xpathdoc as TXMLDocument; // _xpathdoc : the IXMLDocument
在转换函数中。
doc := TXMLDocument(_xpathdoc);
被认为是一种“不安全”的类型转换,如果转换失败,则会返回nil
。更“安全”的转换方式是使用as
运算符,这样如果转换失败就会引发异常:doc := _xpathdoc as TXMLDocument;
。请参阅 Embarcadero 的 DocWiki 上的 Casting Interface References to Objects。 - Remy Lebeau