xmlsubstitution

replace strings in an xml document using a 1:1 replacement file


For a Linux OS to be distributed I have an Openbox menu.xml file that contains about 30 words that would need to be translated for that menu to be localized. I assembled a .csv document with two columns: the English originals in the first (a couple of which include a space), translations in the second. I will be repeating this for something like 12 languages.

Here is a sample menu entry in which "File manager" is the target for translation:

<item label="File manager">
    <action name="Execute"><execute>thunar</execute></action>
  </item>

I need a way to search the menu.xml document string-by-string, replacing all occurrences of a given string with a translation. BTW: functional terms such as execute, action, item etc. do not appear in the csv list.

From an earlier project I have a script in R from my son that works with a flat file (Fluxbox menu) but does not make the substitutions in this case so I hope to find a Bash solution with which I am familiar. Thanks for any help.


Solution

  • Because you said, python could be a solution:

    Updated, for namespace!

    import xml.etree.ElementTree as ET
    import csv
    
    root = ET.parse("menu.xml").getroot()
    ns = {'': 'http://openbox.org/', 'xsi': 'http://www.w3.org/2001/XMLSchema-instance'}
    ET.register_namespace('', "http://openbox.org/")
    
    # csv English, French
    with open("translate.csv", "r") as f:
        csvFile =csv.reader(f)
        for lines in csvFile:
            print(lines[0], lines[1])
    
            for item in root.findall('.//{*}menu', ns):
                for m in item.iter():
                    if m.tag == "{http://openbox.org/}item":
                        if m.get('label') == lines[0]:
                            m.set("label",lines[1].lstrip())
    
    # Pretty Print and write to file
    print()
    tree = ET.ElementTree(root)
    ET.indent(tree, space="  ")
    tree.write("menu_fr.xml", xml_declaration=True, encoding="utf-8")
    
    ET.dump(root)
    

    Output:

    File manager  Gestionnaire de fichiers
    File  fichier
    
    <openbox_menu xmlns="http://openbox.org/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://openbox.org/ file:///usr/share/openbox/menu.xsd">
      <menu id=" ID " label=" TITEL " icon=" SYMBOL ">
        <item label="Gestionnaire de fichiers" icon=" SYMBOL "> AKTIONEN 
      </item>
        <separator label="Überschrift" />
        <menu id=" ID " />
        <separator />
        <menu id=" ID " label=" TITEL " icon=" SYMBOL ">
          <item label="fichier" icon="SYMBOL"> AKTIONEN 
        </item>
        </menu>
        <separator />
        <item label="LABEL" icon="SYMBOL"> AKTIONEN 
      </item>
      </menu>
    </openbox_menu>