so

Org to XML (redux)

Volume 9, Issue 19; 02 Sep 2025

I still want XML out. I still always want XML out.

(This is a revisit of Org to XML from a few years ago. It’s remotely within the bounds of possibility that you might want to look at that for some context before you read what follows.)

I went to publish a weblog post recently and it didn’t work. I got a weird elisp error about comparing nil to -1. My normal weblog posting workflow starts with an Org mode file and winds its way through XML on its way to a database (in Docker containers for local preview) and deeper still into the abyss. Nevermind all that right now.

Trouble was, a couple of weeks earlier, I’d upgraded to Emacs 30 which probably upgraded me to Org mode 9.7.x and may have upgraded the om.el library that I depend on. A quick “I’ll rewind to Emacs 29 and see if that fixes it to get the post published” didn’t fix it. Luckily I could do it by hand.

On Sunday, I set out to fix org-to-xml.

The first thing I discovered was a change to the Org data structures. There’s a new :standard-properties array. The nil was caused by the fact that the :end property had moved into that array. Fixed that. Back in business!

Yeah. Not so much. For very simple documents, that was fine, but for more complex documents, the parsed data structures included “deferred properties” a new feature of Org mode 9.7 that improves performance. (The deferred properties are lazily evaluated.)

Attempting to do string operations on a deferred property is an error.

I could not figure out how to get Org to evaluate deferred properties. It’s possible that I overlooked something in the documentation somewhere, but I tried a good long while. The closest I got was a comment in org-element-ast.el that says:

;; Note that `org-element-copy' unconditionally resolves deferred
;; properties.  This is useful to generate pure (in functional sense)
;; AST.

Except as far as I can tell, it doesn’t. At least, my attempts to copy the objects with org-element-copy did not evaluate their deferred descendants.

Luckily, somewhat randomly and in desperation, I discovered that (org-element-parse-buffer) returns the whole tree with no deferred properties. So I switched to using that. (It’s not entirely clear why I was doing something else in the first place.)

With a few more tweaks, I got it working again. The resulting XML is a little different, but it’s the same in all the fine detail. In fact, my weblog publishing XSLT consumed it without a hitch.

So I can easily make weblog posts again. Which you might consider a good thing or a bad thing, depending.

P.S. I moved the project to Codeberg so in the very unlikely event that you’re also using this package, you’ll want to download the most recent version from there or update your straight.el recipe:

(use-package om-to-xml :straight
  (om-to-xml :type git :host codeberg
             :repo "ndw/org-to-xml" :branch "main"))

Share and enjoy.

#Emacs #Org mode

Please provide your name and email address. Your email address will not be displayed and I won’t spam you, I promise. Your name and a link to your web address, if you provide one, will be displayed.

Your name:

Your email:

Homepage:

Do you comprehend the words on this page? (Please demonstrate that you aren't a mindless, screen-scraping robot.)

What is eight plus three?   (e.g. six plus two is 8)

Enter your comment in the box below. You may style your comment with the CommonMark flavor of Markdown.

All comments are moderated. I don’t promise to preserve all of your formatting and I reserve the right to remove comments for any reason.