This topic contains 8 replies, has 6 voices, and was last updated by  Garry Christensen 2 years, 3 months ago.

Remove Empty XML Tags

  • Hi Guys,

    I am looking for a way to remove empty XML tags.

    Example.

    if the follow do not contain strings/data
    <number>#</number>
    <expiry>#</expiry>

    is it possible to remove the entire tag?

    Regards,
    Fraser

    Did you try node.remove()? Check the online Help for complete description and code snippet.

    You can probably write a little helper function which can iterate through all the XML nodes the tree using nodeType() and :nodeValue() and strip out all the empty tags like this.

    Thanks for the replies guys.

    I’m unable to select the tags i want to remove if they have duplicate names.

    Example:
    <recipient>
    <identifiers>
    <identifier>
    <number></identifier>
    </identifier>
    <identifier>
    <number></identifier>
    </identifier>
    </identifiers>
    </recipient>

    I am wanting to remove the second identifier.
    If i use the following: recipient.identifiers:remove(‘identifier’) it works fine.
    When i use: recipient:child(“identifiers”):remove(“identifier”, 2) i received “2 arguments expected, got 3”.

    I have tried using other methods but can’t seem to figure out a way to remove the second duplicate fields.

    Thanks for your help

    What you’ve provided isn’t valid XML, frazcat, and I’m not quite sure what you’re looking for. Is this more representative of what you’re dealing with?

    <recipient>
          <identifiers>
                <identifier>1234</identifier>
                <identifier></identifier>
                <identifier>3456</identifier>
                <identifier></identifier>
          </identifiers>
    </recipient>
    

    I’ve written a little node method that would turn the above into:

    <recipient>
          <identifiers>
                <identifier>1234</identifier>
                <identifier>3456</identifier>
          </identifiers>
    </recipient>
    

    Is that what you need?

    Jeff Drumm ◊ VP and COO ◊ HICG, LLC. ◊ http://www.hicgrp.com

    I’ve re-read your request and think I’ve figured out what you’re trying to do. The code below will remove only the 2nd child of <recipient> named <identifier>.

    local X  = xml.parse{data=Data}
    local Y  = X.recipient:child('identifiers')
    local id = Y:childCount('identifier')
    for i=Y:childCount(),1,-1 do
       if Y[i]:nodeName() == 'identifier' then
          if id == 2 then
             Y:remove(i)
          else
             id = id - 1
          end
       end
    end
    

    Jeff Drumm ◊ VP and COO ◊ HICG, LLC. ◊ http://www.hicgrp.com

    G’day frazcat,
    I don’t know if this is any use to you but it might give you some ideas. Its some code that I used when building a FHIR interface in Iguana. Essentially, it iterates through an XML node tree and removes any empty nodes. It looks for data in both content and attributes.

    --++++++++++++++++++++++++++++++++++++++++++++++++++
    -- Iterate through a node and delete any empty child nodes
    function node:fhirDropEmpty()
       for nChild = self:childCount(), 1 , -1 do
          if self[nChild]:fhirIsEmpty() then
             self:remove(nChild)
          elseif self[nChild]:nodeName() == 'div' then
          else
             self[nChild]:fhirDropEmpty()
          end
       end 
       return self
    end
    h = {}
    h.Title = 'node:fhirDropEmpty'
    h.Desc = 'Iterates through the node tree and removes any empty nodes'
    h.Usage = 'node:fhirDropEmpty()'
    h.Returns = {}
    h.Returns[1] = {}
    h.Returns[1].Desc = 'Node: a Reference to the node'
    help.set{input_function=node.fhirDropEmpty, help_data=h}
    
    --++++++++++++++++++++++++++++++++++++++++++++++++++
    -- Determines if a node does not contain any data
    function node:fhirIsEmpty()
       local bIsEmpty = true
    
       if self:isLeaf() and self:nodeValue() ~= '' then
          bIsEmpty = false
       elseif self:nodeName() == 'div' and self:childCount() > 0 then
          bIsEmpty = false
       else      
          for n=1, self:childCount() do
             if self:childCount() == 1 and self[1]:nodeName() == 'xmlns' then
             elseif self:childCount() == 1 and self[1]:nodeName() == 'value' and self[1]:nodeValue() ~= '' then
                bIsEmpty = false
                break
             elseif not self[n]:fhirIsEmpty() then
                bIsEmpty = false
                break         
             end
          end
       end
       
       return bIsEmpty
    end
    h = {}
    h.Title = 'node:fhirIsEmpty'
    h.Desc = 'Determines if the node or any of the child nodes contains any valid values'
    h.Usage = 'node:fhirIsEmpty()'
    h.Returns = {}
    h.Returns[1] = {}
    h.Returns[1].Desc = 'Boolean: True if the node or child nodes contains no values, False if values found'
    help.set{input_function=node.fhirIsEmpty, help_data=h}
    

    Thanks, Garry. That code saved me hours!

    My pleasure Brett. I’m glad it helped.

You must be logged in to reply to this topic.