ertank 27 Posted October 10, 2022 Hello, Is it possible to read XML processing instructions using TXMLDocument? Assuming XML I am trying to parse is as follows <?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="xsl_for_this_xml.xslt"?> <DATA xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> </DATA> I am trying to read "href" value in "xml-stylesheet". I will parse it as text if this is not possible to read using existing XML routines in Delphi. Thanks & Regards, Ertan 1 Share this post Link to post
Remy Lebeau 1396 Posted October 10, 2022 (edited) On 10/10/2022 at 2:06 AM, ertank said: Is it possible to read XML processing instructions using TXMLDocument? Yes. You can enumerate the TXMLDocument.Node.ChildNodes list, looking for any children IXMLNode entries whose IXMLNode.NodeType property is ntProcessingInstr and IXMLNode.NodeName property is 'xml-stylesheet'. When you find a match, you will have to parse out its 'href' value from the IXMLNode.NodeValue property. Edited October 11, 2022 by Remy Lebeau 1 Share this post Link to post
ertank 27 Posted October 11, 2022 (edited) 7 hours ago, Remy Lebeau said: You can enumerate the TXMLDocument.Node.ChildNodes list, looking for any children IXMLNode entries whose IXMLNode.NodeType property is ntProcessingInstr Thank you. When I do that, I can find 'xml-stylesheet' node. But, its attribute list is empty. I could read NodeValue though. I used below code for testing. uses Xml.XMLDoc, Xml.XMLIntf; const XmlData = '<?xml version="1.0" encoding="UTF-8"?>' + sLineBreak + '<?xml-stylesheet type="text/xsl" href="xsl_for_this_xml.xslt"?>' + sLineBreak + '<DATA xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' + sLineBreak + '</DATA>'; procedure TForm1.Button1Click(Sender: TObject); var LXml: IXMLDocument; LNode: IXMLNode; begin LXml := NewXMLDocument(); LXml.LoadFromXML(XmlData); LNode := LXml.ChildNodes.First; while LNode <> nil do begin if (LNode.NodeType = ntProcessingInstr) and (LNode.NodeName = 'xml-stylesheet') then begin if LNode.HasAttribute('type') then begin ShowMessage('type: ' + LNode.Attributes['type']); end; if LNode.HasAttribute('href') then begin ShowMessage('href: ' + LNode.Attributes['href']); end; ShowMessage('NodeValue: ' + LNode.NodeValue); Break; end; LNode := LNode.NextSibling; end; end; That only display message NodeValue: type="text/xsl" href="xsl_for_this_xml.xslt". This also leaves a small text parsing. Edited October 11, 2022 by ertank Share this post Link to post
Remy Lebeau 1396 Posted October 11, 2022 (edited) 9 hours ago, ertank said: Thank you. When I do that, I can find 'xml-stylesheet' node. But, its attribute list is empty. I could read NodeValue though. I used below code for testing. If you look at the source code for TXMLDocument, its GetPrologValue() method locates the 'xml' processing instruction and then manually parses out attribute values from its NodeValue. So, I guess that is just the way processing instructions work in the DOM. Which I guess makes sense, as the XML standard defines processing instructions as basically just arbitrary text, they don't actually contain any formal attributes, like element nodes do. But in this case, the text for the 'xml-stylesheet' instruction happens to resemble the syntax of attributes. Edited October 11, 2022 by Remy Lebeau Share this post Link to post