Adressing a node in XML

Published on February 6, 2024

This is another note to my future self. For a project, I wanted to address a given XML node of which I knew the name with something that resembled a path in a folder structure.

Let’s say the XML file in question is this completely contrived example in a file called ‘file.xml’:

  
    
      
        http://example.com/test-system/
      
      
        0
        1
        some_token_or_other
        fortytwo
      
    
  

I needed to reference a node in this file in a format like a path in the directory structure, I.e. like ‘~/tmp/somefile.txt’ for a file ‘somefile.txt’ inside ‘tmp’ in the user’s home directory.

Surprisingly, the IDEs and editors I was using displayed this information, but I couldn’t find a way to copy this to the clipboard.

I reverted to my go-to tool: Ruby (and the Nokogiri Ruby gem). In a Pry session, I only needed these steps:

  1. Load & parse the XML file
  2. Find the node name I was looking for
  3. Get its parent node (and its parent elements…)
  4. Insert the node’s name at the beginning of the list
  5. Combine it into a String

Here’s the abbreviated Pry session:

> pry -r nokogiri
[1] pry(main)> d = Nokogiri::XML(File.open("file.xml"))
=> #(Document:0x140 {
  name = "document",
  --- 8< --- lines were cut out here --- 8< ---
[2] pry(main)> n = d.search('answer').first
=> #(Element:0x1f4 { name = "answer", children = [ #(Text "fortytwo")] })
[3] pry(main)> n.ancestors.map(&:name).unshift(n.name).reverse.join('/')
=> "document/project/test/configuration/parameters/answer"