ElementTree function insert() to accept negative value.
Greetings. This code: import xml.etree.ElementTree as ET e_feed = ET.Element("feed") e_feed.set("xmlns", "http://www.w3.org/2005/Atom") xslt_reference = ET.ProcessingInstruction( "xml-stylesheet", "type=\"text/xml\" href=\"stylesheet.xsl\"") e_feed.insert(0, xslt_reference) Would yield this result: <feed xmlns="http://www.w3.org/2005/Atom"> <?xml-stylesheet type="text/xml" href="stylesheet.xsl"?> </feed> Would it be sensible to allow a negative value: e_feed.insert(-1, xslt_reference) So that the result be: <?xml-stylesheet type="text/xml" href="stylesheet.xsl"?> <feed xmlns="http://www.w3.org/2005/Atom"> </feed> Regards, Schimon
Greetings. Alternatively, it would probably be good to add a new keyword argument to function write() to xml.etree.ElementTree. def write(self, file_or_filename, encoding=None, xml_declaration=None, default_namespace=None, method=None, *, short_empty_elements=True, xslt_stylesheet=None): xslt_stylesheetKeyword argument would only need to include filename (that is, pathname) or basename, as developer requires. Where is the best appropriate venue to ask for such enhancement? Kind regards, Schimon On Sat, 14 Jun 2025 21:33:52 +0300 Schimon Jehudah via lxml - The Python XML Toolkit <lxml@python.org> wrote:
Greetings.
This code:
import xml.etree.ElementTree as ET
e_feed = ET.Element("feed") e_feed.set("xmlns", "http://www.w3.org/2005/Atom") xslt_reference = ET.ProcessingInstruction( "xml-stylesheet", "type=\"text/xml\" href=\"stylesheet.xsl\"") e_feed.insert(0, xslt_reference)
Would yield this result:
<feed xmlns="http://www.w3.org/2005/Atom"> <?xml-stylesheet type="text/xml" href="stylesheet.xsl"?> </feed>
Would it be sensible to allow a negative value:
e_feed.insert(-1, xslt_reference)
So that the result be:
<?xml-stylesheet type="text/xml" href="stylesheet.xsl"?> <feed xmlns="http://www.w3.org/2005/Atom"> </feed>
Regards, Schimon
On 14/06/25 20:33, Schimon Jehudah via lxml - The Python XML Toolkit wrote:> Would it be sensible to allow a negative value:
e_feed.insert(-1, xslt_reference)
If you test this, you will find out that inserting at negative indexes is already a valid operation: `insert(-x, el)` inserts at index `x` *from the end*. This is the normal behaviour of indexing in Python. And if you were using lxml, which you are not (lxml and xml.etree are different packages), what you request would already work if you used the `addprevious` method:
e_feed = ET.Element("feed") e_feed.set("xmlns", "http://www.w3.org/2005/Atom") xslt_reference = ET.ProcessingInstruction( ... "xml-stylesheet", ... "type=\"text/xml\" href=\"stylesheet.xsl\"")
ET.tostring(ET.ElementTree(e_feed)) b'<feed xmlns="http://www.w3.org/2005/Atom"/>' e_feed.addprevious(xslt_reference) ET.tostring(ET.ElementTree(e_feed)) b'<?xml-stylesheet type="text/xml" href="stylesheet.xsl"?><feed xmlns="http://www.w3.org/2005/Atom"/>'
The way you namespace the element is also very much a serialization hack, you should create the element using a QName tag or Clark's Notation. You can use `register_namespace` to force the namespace prefix if you care:
doc1 = ET.Element('{foo}bar') doc2 = ET.Element(ET.QName('foo', 'bar')) ET.tostring(doc1), ET.tostring(doc2) (b'<ns0:bar xmlns:ns0="foo" />', b'<ns0:bar xmlns:ns0="foo" />') ET.register_namespace('', 'foo') ET.tostring(doc1), ET.tostring(doc2) (b'<bar xmlns="foo" />', b'<bar xmlns="foo" />')
in lxml you can also use the nsmap feature:
etree.tostring(etree.Element('{foo}bar', nsmap={None: 'foo'})) b'<bar xmlns="foo"/>'
Xavier. Good evening. I beg your pardon, Please kindly tell me from where did you import ET, as I receive this error after ecevuting ET.tostring(ET.ElementTree(e_feed)). AttributeError: 'ElementTree' object has no attribute 'tag' Regards, Schimon On Mon, 16 Jun 2025 08:04:01 +0200 Xavier Morel <xmo@odoo.com> wrote:
On 14/06/25 20:33, Schimon Jehudah via lxml - The Python XML Toolkit wrote:> Would it be sensible to allow a negative value:
e_feed.insert(-1, xslt_reference)
If you test this, you will find out that inserting at negative indexes is already a valid operation: `insert(-x, el)` inserts at index `x` *from the end*.
This is the normal behaviour of indexing in Python.
And if you were using lxml, which you are not (lxml and xml.etree are different packages), what you request would already work if you used the `addprevious` method:
e_feed = ET.Element("feed") e_feed.set("xmlns", "http://www.w3.org/2005/Atom") xslt_reference = ET.ProcessingInstruction( ... "xml-stylesheet", ... "type=\"text/xml\" href=\"stylesheet.xsl\"")
ET.tostring(ET.ElementTree(e_feed)) b'<feed xmlns="http://www.w3.org/2005/Atom"/>' e_feed.addprevious(xslt_reference) ET.tostring(ET.ElementTree(e_feed)) b'<?xml-stylesheet type="text/xml" href="stylesheet.xsl"?><feed xmlns="http://www.w3.org/2005/Atom"/>'
The way you namespace the element is also very much a serialization hack, you should create the element using a QName tag or Clark's Notation. You can use `register_namespace` to force the namespace prefix if you care:
doc1 = ET.Element('{foo}bar') doc2 = ET.Element(ET.QName('foo', 'bar')) ET.tostring(doc1), ET.tostring(doc2) (b'<ns0:bar xmlns:ns0="foo" />', b'<ns0:bar xmlns:ns0="foo" />') ET.register_namespace('', 'foo') ET.tostring(doc1), ET.tostring(doc2) (b'<bar xmlns="foo" />', b'<bar xmlns="foo" />')
in lxml you can also use the nsmap feature:
etree.tostring(etree.Element('{foo}bar', nsmap={None: 'foo'})) b'<bar xmlns="foo"/>'
Hi Schimon, You've been using Python's built-in ElementTree implementation (xml.etree.ElementTree). This mailing list, and Xavier's guidance, is for the "lxml" package <https://lxml.de/>. So, ensure you've got lxml available within your project (e.g. "pip install lxml") and then import with: import lxml.etree as ET This allows your code below to run. ...although lxml's tutorial <https://lxml.de/tutorial.html> includes the package in the following manner: from lxml import etree If you import in this manner you'd need to update your code, changing the "ET" references to "etree", so something like: from lxml import tree e_feed = etree.Element("feed") e_feed.set("xmlns", "http://www.w3.org/2005/Atom") xslt_reference = etree.ProcessingInstruction( "xml-stylesheet", "type=\"text/xml\" href=\"stylesheet.xsl\"") e_feed.insert(0, xslt_reference) etree.tostring(etree.ElementTree(e_feed)) Cheers aid
On 18 Jun 2025, at 20:10, Schimon Jehudah via lxml - The Python XML Toolkit <lxml@python.org> wrote:
Xavier. Good evening.
I beg your pardon,
Please kindly tell me from where did you import ET, as I receive this error after ecevuting ET.tostring(ET.ElementTree(e_feed)).
AttributeError: 'ElementTree' object has no attribute 'tag'
Regards, Schimon
On Mon, 16 Jun 2025 08:04:01 +0200 Xavier Morel <xmo@odoo.com> wrote:
On 14/06/25 20:33, Schimon Jehudah via lxml - The Python XML Toolkit wrote:> Would it be sensible to allow a negative value:
e_feed.insert(-1, xslt_reference)
If you test this, you will find out that inserting at negative indexes is already a valid operation: `insert(-x, el)` inserts at index `x` *from the end*.
This is the normal behaviour of indexing in Python.
And if you were using lxml, which you are not (lxml and xml.etree are different packages), what you request would already work if you used the `addprevious` method:
e_feed = ET.Element("feed") e_feed.set("xmlns", "http://www.w3.org/2005/Atom") xslt_reference = ET.ProcessingInstruction( ... "xml-stylesheet", ... "type=\"text/xml\" href=\"stylesheet.xsl\"")
ET.tostring(ET.ElementTree(e_feed)) b'<feed xmlns="http://www.w3.org/2005/Atom"/>' e_feed.addprevious(xslt_reference) ET.tostring(ET.ElementTree(e_feed)) b'<?xml-stylesheet type="text/xml" href="stylesheet.xsl"?><feed xmlns="http://www.w3.org/2005/Atom"/>'
The way you namespace the element is also very much a serialization hack, you should create the element using a QName tag or Clark's Notation. You can use `register_namespace` to force the namespace prefix if you care:
doc1 = ET.Element('{foo}bar') doc2 = ET.Element(ET.QName('foo', 'bar')) ET.tostring(doc1), ET.tostring(doc2) (b'<ns0:bar xmlns:ns0="foo" />', b'<ns0:bar xmlns:ns0="foo" />') ET.register_namespace('', 'foo') ET.tostring(doc1), ET.tostring(doc2) (b'<bar xmlns="foo" />', b'<bar xmlns="foo" />')
in lxml you can also use the nsmap feature:
etree.tostring(etree.Element('{foo}bar', nsmap={None: 'foo'})) b'<bar xmlns="foo"/>'
lxml - The Python XML Toolkit mailing list -- lxml@python.org To unsubscribe send an email to lxml-leave@python.org https://mail.python.org/mailman3//lists/lxml.python.org Member address: aid@logic.org.uk
Adrian. Good afternoon. I did not realize it. I, now, know. Thank you, Schimon On Thu, 19 Jun 2025 06:19:01 +0100 Adrian Bool <aid@logic.org.uk> wrote:
Hi Schimon,
You've been using Python's built-in ElementTree implementation (xml.etree.ElementTree).
This mailing list, and Xavier's guidance, is for the "lxml" package <https://lxml.de/>.
So, ensure you've got lxml available within your project (e.g. "pip install lxml") and then import with:
import lxml.etree as ET
This allows your code below to run.
...although lxml's tutorial <https://lxml.de/tutorial.html> includes the package in the following manner:
from lxml import etree
If you import in this manner you'd need to update your code, changing the "ET" references to "etree", so something like:
from lxml import tree
e_feed = etree.Element("feed") e_feed.set("xmlns", "http://www.w3.org/2005/Atom") xslt_reference = etree.ProcessingInstruction( "xml-stylesheet", "type=\"text/xml\" href=\"stylesheet.xsl\"") e_feed.insert(0, xslt_reference)
etree.tostring(etree.ElementTree(e_feed))
Cheers
aid
On 18 Jun 2025, at 20:10, Schimon Jehudah via lxml - The Python XML Toolkit <lxml@python.org> wrote:
Xavier. Good evening.
I beg your pardon,
Please kindly tell me from where did you import ET, as I receive this error after ecevuting ET.tostring(ET.ElementTree(e_feed)).
AttributeError: 'ElementTree' object has no attribute 'tag'
Regards, Schimon
On Mon, 16 Jun 2025 08:04:01 +0200 Xavier Morel <xmo@odoo.com> wrote:
On 14/06/25 20:33, Schimon Jehudah via lxml - The Python XML Toolkit wrote:> Would it be sensible to allow a negative value:
e_feed.insert(-1, xslt_reference)
If you test this, you will find out that inserting at negative indexes is already a valid operation: `insert(-x, el)` inserts at index `x` *from the end*.
This is the normal behaviour of indexing in Python.
And if you were using lxml, which you are not (lxml and xml.etree are different packages), what you request would already work if you used the `addprevious` method:
e_feed = ET.Element("feed") e_feed.set("xmlns", "http://www.w3.org/2005/Atom") xslt_reference = ET.ProcessingInstruction( ... "xml-stylesheet", ... "type=\"text/xml\" href=\"stylesheet.xsl\"")
ET.tostring(ET.ElementTree(e_feed)) b'<feed xmlns="http://www.w3.org/2005/Atom"/>' e_feed.addprevious(xslt_reference) ET.tostring(ET.ElementTree(e_feed)) b'<?xml-stylesheet type="text/xml" href="stylesheet.xsl"?><feed xmlns="http://www.w3.org/2005/Atom"/>'
The way you namespace the element is also very much a serialization hack, you should create the element using a QName tag or Clark's Notation. You can use `register_namespace` to force the namespace prefix if you care:
doc1 = ET.Element('{foo}bar') doc2 = ET.Element(ET.QName('foo', 'bar')) ET.tostring(doc1), ET.tostring(doc2) (b'<ns0:bar xmlns:ns0="foo" />', b'<ns0:bar xmlns:ns0="foo" />') ET.register_namespace('', 'foo') ET.tostring(doc1), ET.tostring(doc2) (b'<bar xmlns="foo" />', b'<bar xmlns="foo" />')
in lxml you can also use the nsmap feature:
etree.tostring(etree.Element('{foo}bar', nsmap={None: 'foo'}))
b'<bar xmlns="foo"/>'
lxml - The Python XML Toolkit mailing list -- lxml@python.org To unsubscribe send an email to lxml-leave@python.org https://mail.python.org/mailman3//lists/lxml.python.org Member address: aid@logic.org.uk
Xavier. Good afternoon. After realizing that I had to import from lxml, it wroks. https://git.xmpp-it.net/sch/publish-happy/commit/87d76d2585c58183752bfb0b80b... I have failed with the namespaces, and I shall try again. Thank you, Schimon On Mon, 16 Jun 2025 08:04:01 +0200 Xavier Morel <xmo@odoo.com> wrote:
On 14/06/25 20:33, Schimon Jehudah via lxml - The Python XML Toolkit wrote:> Would it be sensible to allow a negative value:
e_feed.insert(-1, xslt_reference)
If you test this, you will find out that inserting at negative indexes is already a valid operation: `insert(-x, el)` inserts at index `x` *from the end*.
This is the normal behaviour of indexing in Python.
And if you were using lxml, which you are not (lxml and xml.etree are different packages), what you request would already work if you used the `addprevious` method:
e_feed = ET.Element("feed") e_feed.set("xmlns", "http://www.w3.org/2005/Atom") xslt_reference = ET.ProcessingInstruction( ... "xml-stylesheet", ... "type=\"text/xml\" href=\"stylesheet.xsl\"")
ET.tostring(ET.ElementTree(e_feed)) b'<feed xmlns="http://www.w3.org/2005/Atom"/>' e_feed.addprevious(xslt_reference) ET.tostring(ET.ElementTree(e_feed)) b'<?xml-stylesheet type="text/xml" href="stylesheet.xsl"?><feed xmlns="http://www.w3.org/2005/Atom"/>'
The way you namespace the element is also very much a serialization hack, you should create the element using a QName tag or Clark's Notation. You can use `register_namespace` to force the namespace prefix if you care:
doc1 = ET.Element('{foo}bar') doc2 = ET.Element(ET.QName('foo', 'bar')) ET.tostring(doc1), ET.tostring(doc2) (b'<ns0:bar xmlns:ns0="foo" />', b'<ns0:bar xmlns:ns0="foo" />') ET.register_namespace('', 'foo') ET.tostring(doc1), ET.tostring(doc2) (b'<bar xmlns="foo" />', b'<bar xmlns="foo" />')
in lxml you can also use the nsmap feature:
etree.tostring(etree.Element('{foo}bar', nsmap={None: 'foo'})) b'<bar xmlns="foo"/>'
participants (3)
-
Adrian Bool -
Schimon Jehudah -
Xavier Morel