Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml Delphi将子元素添加到XPath结果_Xml_Delphi_Xpath - Fatal编程技术网

Xml Delphi将子元素添加到XPath结果

Xml Delphi将子元素添加到XPath结果,xml,delphi,xpath,Xml,Delphi,Xpath,难以区分IDOMNode和IXMLNode。 我想将文档中的子元素附加到使用XPath选择的节点 我尝试的是: 努力1: 我从IDOMNodeSelect.selectNodes(表达式)中获得一个XPath结果节点N:IDOMNode 如果我使用 intfDocAccess : IXmlDocumentAccess; doc: TXMLDocument; ... if Supports( N.OwnerDocument, IXmlDocumentAccess, intfDocAccess) t

难以区分IDOMNode和IXMLNode。 我想将文档中的子元素附加到使用XPath选择的节点

我尝试的是:

努力1:

我从
IDOMNodeSelect.selectNodes(表达式)中获得一个XPath结果节点N:IDOMNode
如果我使用

intfDocAccess : IXmlDocumentAccess;
doc: TXMLDocument;
...
if Supports( N.OwnerDocument, IXmlDocumentAccess, intfDocAccess) then
    doc := intfDocAccess.DocumentObject
  else
    doc := nil;
  NodeAsIXMLNode := TXmlNode.Create( N, nil, doc );
…然后向其中添加子项会引发访问冲突。可能NodeAsIXMLNode甚至不在原始文档中,它只是为了类型兼容性而创建的副本

努力2:

尝试直接将子节点添加到XPath结果节点:

XMLNode := XmlDoc.CreateElement( 'tag', '' );
N.appendChild( XMLNode as IDOMNode );
它抛出不支持的接口。我感觉xpath结果IDOMNode节点也不是原始IXMLDocument的成员,只是一些结果副本。只是猜测而已

那么,如何使用xpath选择一个节点,然后向其附加一个子元素节点呢? 因此,我的原始IXML文档得到更新

更新: 遍历整个xml文档树,并将IXMLNode的DOMNode与XPath结果DOMNode进行比较,发现DOMNode也不起作用——原始文档中不包含XPath结果节点。尝试了msxml、adom和omnixml实现/XE7/

更新2: 设法使用第一种方法,只需替换

doc := nil;


在转换器功能中

我不确定这是否有用,但假设您有一个XML文档

<Content>
  <Clients>
    <Client>
      <ID value="88"/>
      <Forename value="John"/>
      <Surname value="Smith"/>
    </Client>
  </Clients>
</Content>
此代码使用D7附带的MSXML.Pas导入单元,并使用当时最新的MSXML.DLL版本(C:\WINDOWS\SYSTEM\MSXML.DLL)生成


就我个人而言,我从未发现Delphi的“抽象”TXmlDocument有帮助——我发现使用MSXML的对象更容易。Ymmv…

XPath仅用于搜索,不用于操作文档。无法将XPath
IDOMNode
转换回原始的
IXMLNode
,并且
selectNodes()
不报告在文档中找到DOM节点的位置。迭代文档以查找匹配的节点违背了使用XPath的目的,您也可以首先手动迭代文档,而不使用XPath。谢谢,也许吧,但既然XPath很方便,为什么不这样使用呢?当然,我可以以一种同时使xpath结果无效的方式操作文档,但我没有。请参阅更新2了解当前的工作方式。请注意
doc:=TXMLDocument(\u xpathdoc)被视为“不安全”类型转换,如果转换失败,将返回
nil
。“安全”强制转换是使用
作为
运算符,因此如果强制转换失败,它会引发异常:
doc:=\u xpathdoc作为TXMLDocument。请参阅Embarcadero的DocWiki。谢谢,根据您的建议更新了上述代码。
<Content>
  <Clients>
    <Client>
      <ID value="88"/>
      <Forename value="John"/>
      <Surname value="Smith"/>
    </Client>
  </Clients>
</Content>
procedure TForm1.btnLoadClick(Sender: TObject);
var
  XmlDoc: IXMLDOMDocument;
  NodeList : IXmlDOMNodeList;
  Node,
  NewNode : IXmlDomNode;
  E : IXmlDomElement;
  TextNode : IXMLDOMText;
  Value : String;
  I : Integer;
begin
  Memo2.Lines.Clear;
  XmlDoc := CoDOMDocument.Create; //CreateOleObject('Microsoft.XMLDOM') as IXMLDOMDocument;
  XmlDoc.Async := False;
  XmlDoc.LoadXML(Memo1.Lines.Text);
  if xmlDoc.parseError.errorCode <> 0 then
    raise Exception.Create('XML Load error:' + xmlDoc.parseError.reason);

  NodeList := XmlDoc.documentElement.SelectNodes(edPathQuery.Text);

  if NodeList.length > 0 then begin
    E := XMLDoc.createElement('Added');
    //  E.nodeValue := 'Something'; Note the error this raises.  Using the
    //  TextNode as below avoids this
    NewNode := E as IXMLDomNode;
    TextNode := XMLDoc.createTextNode('Data');
    NewNode.appendChild(TextNode);
    NodeList.item[0].appendChild(NewNode);
  end;
  Memo2.Lines.Text := XMLDoc.documentElement.xml;
end;