Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2012-06

DOM and namespaces with prefix

5 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Torsten Bonde Christiansen

Hi all.

I am working on implementing a lite export routine from our program to the DDI XML format:
http://www.ddialliance.org/Specification/DDI-Lifecycle/3.1/XMLSchema/

A convinient way of working with the DDI format is to prefix elements using common set of prefix'es, but having spent most of the day trying to I can only make it work with a single prefix.

program project1;
{$mode objfpc}{$H+}
uses
   Classes, DOM, XMLWrite;
var
   XMLDoc: TXMLDocument;
   DDIInstance: TDOMElement;
   Attr: TDOMAttr;
begin
   XMLDoc := TXMLDocument.Create;
   DDIInstance := XMLDoc.CreateElementNS('ddi:instance:3_0', 'DDIInstance');
   DDIInstance.Prefix := 'ns1';        // this gives me:
<ns1:DDIInstance xmlns:ns1="ddi:instance:3_0"> which is great.
   // now I would like to expand with eg: xmlns:a="ddi:archive:3_0"
   Attr := XMLDoc.CreateAttributeNS('ddi:archive:3_0', 'huh');
   Attr.Prefix := 'a';
   DDIInstance.SetAttributeNode(Attr);   // but this gives:
<ns1:DDIInstance xmlns:ns1="ddi:instance:3_0" xmlns:a="ddi:archive:3_0"
a:huh=""/>
   Xmldoc.AppendChild(DDIInstance);
   WriteXMLFile(XMLDOc, '/tmp/test.xml');
end.

How can i get the "xmlns:a="ddi:archive:3_0" without the additional attribute AND maintain the namespace + prefix in later elements?

Kind regards,
Torsten Bonde Christiansen.

Reply by email

Daniel Gaspary
to Torsten Bonde Christiansen
Torsten Bonde Christiansen wrote
How can i get the "xmlns:a="ddi:archive:3_0" without the additional attribute AND maintain the namespace + prefix in later elements?

Hi.

It's hard to test without a (small please) comlete XML example because the NS attribute is added when it's needed. So, you need to add an attribute or a child element that uses the Namespace.

The XML below is created with the modfied program ahead. But I believe a method to create a namespace attribute would be useful.

<?xml version="1.0" encoding="utf-8"?>
<ns1:DDIInstance xmlns:ns1="ddi:instance:3_0">
<a:AnAELement xmlns:a="ddi:archive:3_0">
<a:AnotherAELement a:MyAtt="A value"/>
</a:AnAELement>
</ns1:DDIInstance>

program project1;
{$mode objfpc}{$H+}
uses
 Classes, DOM, XMLWrite;
const
     cArchive = 'ddi:archive:3_0';
var
 XMLDoc: TXMLDocument;
 DDIInstance: TDOMElement;
 AnAElement, AnotherAElement: TDOMElement;
begin
 XMLDoc := TXMLDocument.Create;
 DDIInstance := XMLDoc.CreateElementNS('ddi:instance:3_0', 'DDIInstance');
 DDIInstance.Prefix := 'ns1';        // this gives me:
<ns1:DDIInstance xmlns:ns1="ddi:instance:3_0"> which is great.
 //Here a New element using the Namespace that will be created.
 AnAElement:=XMLDoc.CreateElementNS(cArchive, 'a:AnAELement');
 DDIInstance.AppendChild(AnAElement);
 //Another element of the same namespace, child of the prior, no
Namespace creation
 //needed
 AnotherAElement:=XMLDoc.CreateElementNS(cArchive, 'a:AnotherAELement');
 AnAElement.AppendChild(AnotherAElement);
 //The same as above, but with an Attribute
 AnotherAElement.SetAttributeNS(cArchive, 'a:MyAtt', 'A value');
 Xmldoc.AppendChild(DDIInstance);
 WriteXMLFile(XMLDOc, '/tmp/test.xml');
end.

Reply by email

Daniel Gaspary
to Daniel Gaspary

I have created a bug report[1] with an example of malformed file.

[1] http://bugs.freepascal.org/view.php?id=22299

Daniel Gaspary wrote 60 lines
On Tue, Jun 19, 2012 at 10:11 AM, Torsten Bonde Christiansen wrote: > How can i get the "xmlns:a="ddi:archive:3_0" without the additional > attribute AND maintain the namespace + prefix in later elements? Hi. It's hard to test without a (small please) comlete XML example because the NS attribute is added when it's needed. So, you need to add an attribute or a child element that uses the Namespace. The XML below is created with the modfied program ahead. But I believe a method to create a namespace attribute would be useful. <?xml version="1.0" encoding="utf-8"?> <ns1:DDIInstance xmlns:ns1="ddi:instance:3_0">  <a:AnAELement xmlns:a="ddi:archive:3_0">    <a:AnotherAELement a:MyAtt="A value"/>  </a:AnAELement> </ns1:DDIInstance> program project1; {$mode objfpc}{$H+} uses  Classes, DOM, XMLWrite; const     cArchive = 'ddi:archive:3_0'; var  XMLDoc: TXMLDocument;  DDIInstance: TDOMElement;  AnAElement, AnotherAElement: TDOMElement; begin  XMLDoc := TXMLDocument.Create;  DDIInstance := XMLDoc.CreateElementNS('ddi:instance:3_0', 'DDIInstance');  DDIInstance.Prefix := 'ns1';        // this gives me: <ns1:DDIInstance xmlns:ns1="ddi:instance:3_0"> which is great.  //Here a New element using the Namespace that will be created.  AnAElement:=XMLDoc.CreateElementNS(cArchive, 'a:AnAELement');  DDIInstance.AppendChild(AnAElement);  //Another element of the same namespace, child of the prior, no Namespace creation  //needed  AnotherAElement:=XMLDoc.CreateElementNS(cArchive, 'a:AnotherAELement');  AnAElement.AppendChild(AnotherAElement);  //The same as above, but with an Attribute  AnotherAElement.SetAttributeNS(cArchive, 'a:MyAtt', 'A value');  Xmldoc.AppendChild(DDIInstance);  WriteXMLFile(XMLDOc, '/tmp/test.xml'); end.

Reply by email

Daniel Gaspary
to Torsten Bonde Christiansen: Hi all. I am working on implementing a lite export routine from our program to the DDI…
Torsten Bonde Christiansen wrote 12 lines
 DDIInstance := XMLDoc.CreateElementNS('ddi:instance:3_0', 'DDIInstance');  DDIInstance.Prefix := 'ns1';        // this gives me: <ns1:DDIInstance xmlns:ns1="ddi:instance:3_0"> which is great.  // now I would like to expand with eg: xmlns:a="ddi:archive:3_0"  Attr := XMLDoc.CreateAttributeNS('ddi:archive:3_0', 'huh');  Attr.Prefix := 'a';  DDIInstance.SetAttributeNode(Attr);   // but this gives: <ns1:DDIInstance xmlns:ns1="ddi:instance:3_0" xmlns:a="ddi:archive:3_0" a:huh=""/> How can i get the "xmlns:a="ddi:archive:3_0" without the additional attribute AND maintain the namespace + prefix in later elements?

I believe that the solution(given by Sergei Gorelkin at [1]) is:

DDIInstance.SetAttributeNS('ddi:archive:3_0','xmlns:a','ddi:archive:3_0');

[1] http://bugs.freepascal.org/view.php?id=22299#c60652

Reply by email

Torsten Bonde Christiansen
to Daniel Gaspary
Daniel Gaspary wrote 21 lines
On Tue, Jun 19, 2012 at 10:11 AM, Torsten Bonde Christiansen wrote: > DDIInstance := XMLDoc.CreateElementNS('ddi:instance:3_0', 'DDIInstance'); > DDIInstance.Prefix := 'ns1'; // this gives me: <ns1:DDIInstance > xmlns:ns1="ddi:instance:3_0"> which is great. > > // now I would like to expand with eg: xmlns:a="ddi:archive:3_0" > Attr := XMLDoc.CreateAttributeNS('ddi:archive:3_0', 'huh'); > Attr.Prefix := 'a'; > DDIInstance.SetAttributeNode(Attr); // but this gives: <ns1:DDIInstance > xmlns:ns1="ddi:instance:3_0" xmlns:a="ddi:archive:3_0" a:huh=""/> > How can i get the "xmlns:a="ddi:archive:3_0" without the additional > attribute AND maintain the namespace + prefix in later elements? I believe that the solution(given by Sergei Gorelkin at [1]) is: DDIInstance.SetAttributeNS('ddi:archive:3_0','xmlns:a','ddi:archive:3_0'); [1] http://bugs.freepascal.org/view.php?id=22299#c60652 _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Great - thank you very much!

-Torsten.

Reply by email