python - Modifying an XML File - Dividing values -


i looking modify values in xml file dividing them.

i need divide values se:svgparameter[name="stroke-width"] , se:size 3.6. found tutorial on python.org, modifying xml file, doesn’t seem work , couldn’t find similar on here. or point appreciated!

here's example xml, want able output script in folder multiple files , have convert of them.

xml:

<?xml version="1.0" encoding="iso-8859-1"?> <styledlayerdescriptor version="1.1.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemalocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/styledlayerdescriptor.xsd" xmlns:se="http://www.opengis.net/se">   <namedlayer>     <se:name>qgis_sld_scaleproblem</se:name>     <se:description>       <se:title>qgis_sld_scaleproblem</se:title>       <se:abstract>this sld in pixels, qgis read mm</se:abstract>     </se:description>     <userstyle>       <se:name>qgis_sld_scaleproblem</se:name>       <se:featuretypestyle>         <se:rule>           <se:name>qgis_sld_scaleproblem_line</se:name>           <se:linesymbolizer>             <se:name>line</se:name>             <se:stroke>               <se:svgparameter name="stroke">#ff0000</se:svgparameter>               <se:svgparameter name="stroke-width">36</se:svgparameter>             </se:stroke>           </se:linesymbolizer>         </se:rule>         <se:rule>           <se:name>qgis_sld_scaleproblem_point</se:name>           <se:pointsymbolizer>             <se:name>point</se:name>             <se:graphic>              <se:mark>               <se:wellknownname>circle</se:wellknownname>               <se:fill>                <se:svgparameter name="fill">#ff0000</se:svgparameter>               </se:fill>              </se:mark>              <se:size>36</se:size>             </se:graphic>           </se:pointsymbolizer>         </se:rule>       </se:featuretypestyle>     </userstyle>   </namedlayer> </styledlayerdescriptor> 

code:

import xml.etree.elementtree et lxml import etree  tree = et.parse('qgis-sld-scaleproblem_line.sld') root = tree.getroot()  # check script reading correct file print("sld file", root[0][0].text, "loaded.")  # registers namespaces prevent them being filled defaults et.register_namespace('', "http://www.opengis.net/sld") et.register_namespace('ogc', "http://www.opengis.net/ogc") et.register_namespace('xsi', "http://www.w3.org/2001/xmlschema-instance") et.register_namespace('xlink', "http://www.w3.org/1999/xlink") et.register_namespace('schemalocation', "http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/styledlayerdescriptor.xsd") et.register_namespace('se', "http://www.opengis.net/se")  # section "should" search xml se:svgparameter name="stroke-width" , se:size , divide value 3.6 svgparameter in root.iter('svgparameter'):     new_svgparameter = int(svgparameter.text) / 3.6     svgparameter.text = str(new_svgparameter) size in root.iter('size'):     new_size= int(size.text) / 3.6     size.text = str(new_size)  tree.write("gis-sld-scalefixed.sld", xml_declaration=true, encoding='iso-8859-1') 

answers i’ve looked at:

consider xslt special-purpose language designed transform xml files. , python's lxml module can run xslt 1.0 scripts. plus xslt can run outside python, hence portability.

simply call identity transform copy whole document , run division on selected nodes. no for loops or if logic needed approach.

xslt (save .xsl file, special well-formed xml file)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"                               xmlns:se="http://www.opengis.net/se">                                  <xsl:output indent="yes"/>   <xsl:strip-space elements="*"/>    <xsl:template match="@*|node()">     <xsl:copy>       <xsl:apply-templates select="@*|node()"/>     </xsl:copy>   </xsl:template>    <xsl:template match="se:svgparameter[@name='stroke-width']|se:size">     <xsl:copy>         <xsl:apply-templates select="@*"/>         <xsl:value-of select="format-number(text(), '#') div 3.6"/>     </xsl:copy>   </xsl:template>  </xsl:stylesheet> 

python (iterate below process in loop multiple files)

import lxml.etree et  # load xml , xsl doc = et.parse('input.xml') xsl = et.parse('xsltscript.xsl')  # transform transform = et.xslt(xsl) result = transform(doc)  # output screen     print(result)  # output file open('output.xml', 'wb') f:     f.write(result) 

output

<?xml version="1.0"?> <styledlayerdescriptor xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:se="http://www.opengis.net/se" version="1.1.0" xsi:schemalocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/styledlayerdescriptor.xsd">   <namedlayer>     <se:name>qgis_sld_scaleproblem</se:name>     <se:description>       <se:title>qgis_sld_scaleproblem</se:title>       <se:abstract>this sld in pixels, qgis read mm</se:abstract>     </se:description>     <userstyle>       <se:name>qgis_sld_scaleproblem</se:name>       <se:featuretypestyle>         <se:rule>           <se:name>qgis_sld_scaleproblem_line</se:name>           <se:linesymbolizer>             <se:name>line</se:name>             <se:stroke>               <se:svgparameter name="stroke">#ff0000</se:svgparameter>               <se:svgparameter name="stroke-width">10</se:svgparameter>             </se:stroke>           </se:linesymbolizer>         </se:rule>         <se:rule>           <se:name>qgis_sld_scaleproblem_point</se:name>           <se:pointsymbolizer>             <se:name>point</se:name>             <se:graphic>               <se:mark>                 <se:wellknownname>circle</se:wellknownname>                 <se:fill>                   <se:svgparameter name="fill">#ff0000</se:svgparameter>                 </se:fill>               </se:mark>               <se:size>10</se:size>             </se:graphic>           </se:pointsymbolizer>         </se:rule>       </se:featuretypestyle>     </userstyle>   </namedlayer> </styledlayerdescriptor> 

Comments

Popular posts from this blog

neo4j - finding mutual friends in a cypher statement starting with three or more persons -

php - How to remove letter in front of the word laravel -

minify - Minimizing css files -