2017-09-12 10 views
1

xmlファイル内の値を必ず分割して変更することを検討しています。XMLファイルを変更する - 値を分割する

se:SvgParameter[name="stroke-width"]se:Sizeの値を3.6で割る必要があります。私はこのチュートリアルをPython.orgのModifying an XML Fileで見つけましたが、動作していないようで、私はここで似たようなものを見つけることができませんでした。どんな助けや指摘も大歓迎です!

XMLの例ですが、複数のファイルがあるフォルダにスクリプトを出力し、そのすべてを変換する必要があります。

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 is in Pixels, but QGIS will read it as 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> 

コード:私が見てきた

import xml.etree.ElementTree as ET 
from lxml import etree 

tree = ET.parse('QGIS-SLD-ScaleProblem_Line.sld') 
root = tree.getroot() 

# To check that the script is reading the correct file 
print("SLD file", root[0][0].text, "loaded.") 

# Registers namespaces to prevent them being filled with 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") 

# This section "should" search the XML for se:SvgParameter name="stroke-width" and se:Size and divide the value by 3.6 
for SvgParameter in root.iter('SvgParameter'): 
    new_SvgParameter = int(SvgParameter.text)/3.6 
    SvgParameter.text = str(new_SvgParameter) 
for 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') 

回答:

答えて

0

XMLファイルを変換するために設計されたXSLT特別な目的の言語を考えてみましょう。 Pythonのlxmlモジュールでは、XSLT 1.0スクリプトを実行できます。プラスXSLTはPythonの外部で実行できるため、移植性が向上します。

identity transformに電話してドキュメント全体をそのままコピーし、選択したノードで部門を実行してください。 forループまたはifロジックが必要です。

XSLT(、特殊な整形式のXMLファイルをなどの.xslファイルを保存)

<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> 

パイソン(複数ファイルのため、ループ内のプロセスの下に反復)

import lxml.etree as et 

# LOAD XML AND XSL 
doc = et.parse('Input.xml') 
xsl = et.parse('XSLTScript.xsl') 

# TRANSFORM 
transform = et.XSLT(xsl) 
result = transform(doc) 

# OUTPUT TO SCREEN  
print(result) 

# OUTPUT TO FILE 
with open('Output.xml', 'wb') as f: 
    f.write(result) 

出力

<?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 is in Pixels, but QGIS will read it as 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> 
+0

ありがとうございました!これはまさに私が後にしたものです!私はXSLTについてもっと学ぶ必要があると思います! –

関連する問題