Adding an attribute to every XML element in an XLIFF file - python

I want to add xml:space="preserve" to every element in Xliff files like this one:
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file datatype="plaintext" source-language="en-US" target-language="de-DE" date="2023-01-19T14:30:55Z" xml:space="preserve">
<body>
<trans-unit size-unit="char" approved="no" maxwidth="70" id="TITLE">
<source>Add test scripts to execution queue</source>
<target state="translated">Testskripte zur Ausführungs-Queue hinzufügen</target>
</trans-unit>
<trans-unit size-unit="char" approved="no">
<source>Dynamic ID</source>
<target state="translated">Dynamic-ID</target>
</trans-unit>
<trans-unit size-unit="char" approved="no" maxwidth="132">
<source>Identification</source>
<target state="translated">Identifikation</target>
</trans-unit>
</body>
</file>
</xliff>
The Python script I have looks like this, but also adds ns0: to the beginning of each element in the XML file.
import xml.etree.ElementTree as ET
tree = ET.parse("input.xlf")
root = tree.getroot()
for trans_unit in root.iter("{urn:oasis:names:tc:xliff:document:1.2}trans-unit"):
trans_unit.attrib["{http://www.w3.org/XML/1998/namespace}space"] = "preserve"
tree.write("output.xlf")
Why does that happen and can someone help to improve the script?

OK, adding ET.register_namespace("", "urn:oasis:names:tc:xliff:document:1.2")
and then also encoding='utf-8', xml_declaration=True) to the tree.write statement did the trick.
Thanks, #mzjn!

Related

How to replace xml lines using 'if statements' in python?

Hi I'm new to xml files in general, but I am trying to replace specific lines in a xml file using 'if statements' in python 3.6. I've been looking at suggestions to use ElementTree, but none of the posts online quite fit the problem I have, so here I am.
My file is as followed:
<?xml version="1.0" encoding="UTF-8"?>
-<StructureDefinition xmlns="http://hl7.org/fhir">
<url value="http://example.org/fhir/StructureDefinition/MyObservation"/>
<name value="MyObservation"/>
<status value="draft"/>
<fhirVersion value="3.0.1"/>
<kind value="resource"/>
<abstract value="false"/>
<type value="Observation"/>
<baseDefinition value="http://hl7.org/fhir/StructureDefinition/Observation"/>
<derivation value="constraint"/>
</StructureDefinition>
I want to replace
url value="http://example.org/fhir/StructureDefinition/MyObservation"/
to something like
url value="http://example.org/fhir/StructureDefinition/NewObservation"/
by using conditional statements - because these are repeated multiple times in other files.
I have tried for-looping through the xml find to find the exact string match (which I've succeeded), but I wasn't able to delete, or replace the line (probably having to do with the fact that this isn't a .txt file).
Any help is greatly appreciated!
Your sample file contains a "-"-token in ln 3 that may be overlooked when copy/pasting in order to find a solution.
Input File
<?xml version="1.0" encoding="UTF-8"?>
<StructureDefinition xmlns="http://hl7.org/fhir">
<url value="http://example.org/fhir/StructureDefinition/MyObservation"/>
<name value="MyObservation"/>
<status value="draft"/>
<fhirVersion value="3.0.1"/>
<kind value="resource"/>
<abstract value="false"/>
<type value="Observation"/>
<baseDefinition value="http://hl7.org/fhir/StructureDefinition/Observation"/>
<derivation value="constraint"/>
</StructureDefinition>
Script
from xml.dom.minidom import parse # use minidom for this task
dom = parse('june.xml') #read in your file
search = "http://example.org/fhir/StructureDefinition/MyObservation" #set search value
replace = "http://example.org/fhir/StructureDefinition/NewObservation" #set replace value
res = dom.getElementsByTagName('url') #iterate over url tags
for element in res:
if element.getAttribute('value') == search: #in case of match
element.setAttribute('value', replace) #replace
with open('june_updated.xml', 'w') as f:
f.write(dom.toxml()) #update the dom, save as new xml file
Output file
<?xml version="1.0" ?><StructureDefinition xmlns="http://hl7.org/fhir">
<url value="http://example.org/fhir/StructureDefinition/NewObservation"/>
<name value="MyObservation"/>
<status value="draft"/>
<fhirVersion value="3.0.1"/>
<kind value="resource"/>
<abstract value="false"/>
<type value="Observation"/>
<baseDefinition value="http://hl7.org/fhir/StructureDefinition/Observation"/>
<derivation value="constraint"/>
</StructureDefinition>

Python xml elementree how to check if element if present and process code?

<rules>
<entry name="rule name 1">
<to>
<member>untrust</member>
</to>
<from>
<member>trust</member>
</from>
<source>
<member>object1</member>
</source>
<destination>
<member>any</member>
</destination>
<service>any</service>
<description>'NAT Rule 1'</description>
<nat-type>ipv4</nat-type>
<source-translation>
<static-ip>
<bi-directional>yes</bi-directional>
<translated-address>object1-pub</translated-address>
</static-ip>
</source-translation>
</entry>
<entry name="rule name 2">
<to>
<member>untrust</member>
</to>
<from>
<member>trust</member>
</from>
<source>
<member>any</member>
</source>
<destination>
<member>object2-pub</member>
</destination>
<destination-translation>
<translated-address>object2</translated-address>
</destination-translation>
<service>any</service>
<description>'NAT Rule 2'</description>
<tag>
<member>DST NAT</member>
</tag>
</entry>
</rules>
Hi,
I am trying to process above xml using xml elementree in python. I am looking for a way to check if the <'source-traslation'> or <'destination-translation'> is present. In short, if it if source-translation then set nat-type varialble to source nat and proceed further to get and <'translated-address'> values. If <'destination-address'> is present then process logic to get values for . I am putting all this data in a dict with a format like this...
rules{
rule_name: <name>
options:{
src_zone:<from>
source:<source>
dst_zone:<to>
destination:<destination>
nat-type:<appliaction>
service:<service>
traslated-address:<translated-address>
destination-address:<destination-address>
}
}
I have tried various combinations however it is not working for me.
To check if your element exists you can have an if statement like this:
import xml.etree.ElementTree as ET
root = ET.parse('PATH_TO_YOUR_FILE').getroot()
if len(root.findall('source-translation')) > 0:
PUT YOUR CODE HERE

Using python, elementtree, xml parser to get attributes not working for some reason?

I'm new to python and parsing xml, but I'm having trouble with a particular xml file which is spat out by a program I work with. I'm trying parse this xml file using python and elementtree in order to extract the url data (the URL below is fake). Any ideas as to why this isn't working?
my python code:
def xmlTreeParser(fileName,attribute,tagName):
tree = ET.parse(fileName)
root = tree.getroot()
attribArray = [element.attrib[attribute] for element in root.findall(tagName)]
print attribArray
xmlTreeParser("xml_file.xml",'text','Expr')
here's my xml file:
<Query id="f9cef041-085d-47e0-8d16-15e36bba1ec8" name="">
<Description />
<JustSortedColumns />
<Conditions linking="All">
<Condition class="PDCT" enabled="True" readOnly="False" linking="Any">
<Condition class="SMPL" enabled="True" readOnly="False">
<Operator id="Contains" />
<Expressions>
<Expr class="ENTATTR" id="Person.LinkedInUrl" />
<Expr class="CONST" type="String" kind="Scalar" value="https://www.linkedin.com/Bill-Smith" text="https://www.linkedin.com/Bill-Smith" />
</Expressions>
</Condition>
</Condition>
</Conditions>
</Query>
The python I wrote works just fine on another, test, xml file that I wrote myself. I'm at a loss as to why I can't parse this particular block of xml. Thanks everyone.
For the specific call you make, you need to add this syntax to reach the tag Expr (doc):
xmlTreeParser("xml_file.xml",'text','.//Expr')
But also your Xml doesn't have all attributes like text, you should prevent errors like this :
attribArray = [element.attrib.get(attribute, '') for element in root.findall(tagName)]
# -----------------------------^
print(attribArray)
xmlTreeParser("xml_file.xml",'text','.//Expr')

how to change a node value in python

<?xml version="1.0"?>
<info>
</tags>
</tags>
<area>
<media>
<options>
<name>Jaipur</name>
</options>
</media>
</area>
</info>
i am totaly new in python, here is my xml file and i want to edit element value at run time in python
it means I want to change the <name>Jaipur</name> to <name>Mumbai</name>
First, the example is not valid xml. You can use xml.etree that comes included:
from xml.etree import ElementTree as et
xmlstr="""\
<?xml version="1.0"?>
<area>
<media>
<options>
<name>Jaipur</name>
</options>
</media>
</area>"""
doc=et.fromstring(xmlstr)
doc.find('.//name').text='Mumbai'
print et.tostring(doc)
output:
<area>
<media>
<options>
<name>Mumbai</name>
</options>
</media>
</area>

Add a line to a file if it not exist using python

I have an xml file as follows:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build" ToolsVersion="4.0">
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
I want to add a line <Import Project="$(ProjectName).targets" /> between
</ImportGroup> and </Project> as follows
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build" ToolsVersion="4.0">
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<Import Project="$(ProjectName).targets" />
</Project>
If the line <Import Project="$(ProjectName).targets" /> already exists in file there is no need to add.
How can I do that?
Your question is based on lines in text files, but the input file is clearly XML, so assuming you actually want to add an Import if it doesn't exist, try this:
import xml.dom.minidom
importstring = "$(Projectname).targets"
filename = "test.xml"
tree = xml.dom.minidom.parse(filename)
Project = tree.getElementsByTagName("Project")[0]
for Import in Project.getElementsByTagName("Import"):
if Import.getAttribute("Project") == importstring:
break
else: # note this is else belongs to the for, not the if
newImport = xml.dom.minidom.Element("Import")
newImport.setAttribute("Project", importstring)
Project.appendChild(newImport)
tree.writexml(open(filename, 'w'))
Take the XML parser of your choice, parse the file, manipulate the file using the related API, write it back.

Categories