Search code examples
pythonxmldomminidom

adding nodes to xml file with same node name but different attributes with Python Dom



is it possible to add two nodes with the same name to a xml document ?
That is something like that :
Initial file :

<Files>
  <Filter>
  </Filter>
</Files>

Wanted file :

<Files>
  <Filter>
    <File RelativePath=".\src\aaa.cxx" ></File>
    <File RelativePath=".\src\bbb.cxx"></File>
  </Filter>
</Files>

I would like to do that with Python, dom or minidom.
I tried to use the appendChild function but if only keep one node of the same name.
I tried to use the insertBefore function but it doesn't seem to work also.

Here is the source code I used with insertBefore (with appendChild, just have to remove the nbOfFiles control) :

document = xml.dom.minidom.parse (fileTmp)
filesItem = Item.getElementsByTagName("Files")[0]
for filter in filesItem.getElementsByTagName("Filter") :
  filterAttribute      = filter.getAttribute("Filter")
  filePath = os.path.split (fileTmp)[0] + "/src"
  filesInPath = os.listdir (filePath)
  fileElement = document.createElement ("File")
  nbOfFiles = 0
  for file in filesInPath :
    fileElement.setAttribute ("RelativePath", file)
    if nbOfFiles == 0 :
      filter.appendChild (fileElement)
      lastFileElement = fileElement
      nbOfFiles = nbOfFiles + 1
    else :
      filter.insertBefore (fileElement, None)

Thanks for your help.


Solution

  • Not sure where your code is going wrong, as you've not provided a testable example. I'm not particularly familiar with minidom, I prefer lxml.

    I suspect you need to instantiate each new child node separately.

    This works for me:

    >>> import xml.dom.minidom
    >>>
    >>> data_in = """<Files>
    ...   <Filter>
    ...   </Filter>
    ... </Files>
    ... """
    >>>
    >>> data_add = ('./src/aaa.cxx','./src/bbb.cxx')
    >>>
    >>> doc = xml.dom.minidom.parseString(data_in)
    >>> files= doc.getElementsByTagName("Files")[0]
    >>> for filter in files.getElementsByTagName("Filter"):
    ...   for item in data_add:
    ...     newNode = doc.createElement("File")
    ...     newNode.setAttribute('RelativePath',item)
    ...     filter.appendChild(newNode)
    ...
    <DOM Element: File at 0x984c66c>
    <DOM Element: File at 0x984c80c>
    >>> print doc.toxml()
    <?xml version="1.0" ?>
    <Files>
      <Filter>
      <File RelativePath="./src/aaa.cxx"/><File RelativePath="./src/bbb.cxx"/></Filter>
    </Files>