Jump to content
ertank

Reading processing instructions from XML

Recommended Posts

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

  • Like 1

Share this post


Link to post
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 by Remy Lebeau
  • Like 1

Share this post


Link to post
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 by ertank

Share this post


Link to post
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 by Remy Lebeau

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×