2017-08-24 5 views
0

現在、私はPythonスクリプトを書くことで、あるタイプのXMLからあるタイプのSLDを変換しようとしています。私は2週間近く頭を強くしていて、ほとんど進展していない。 私はPythonには本当に新しいですし、任意の提案を感謝します!
基本的に、私はこれを回す必要があります...。このPythonを使ってSLDを1.1から1.0に変換する

<?xml version="1.0" encoding="UTF-8"?> 
<StyledLayerDescriptor version="1.0.0" xmlns="http://www.opengis.net/sld" 
xmlns:ogc="http://www.opengis.net/ogc" 
xmlns:gml="http://www.opengis.net/gml" 
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.0.0/StyledLayerDescriptor.xsd"> 
<NamedLayer> 
<Name>Custom_Landuse</Name> 
<UserStyle> 
    <Name>Land Use</Name> 
    <FeatureTypeStyle> 
    <Rule> 
     <Name>Woods</Name> 
     <Title>Woods - 1:65,000 to 1:150,000</Title> 
     <Abstract>A Land Use style</Abstract> 
     <ogc:Filter> 
     <ogc:PropertyIsEqualTo> 
      <ogc:PropertyName>AREA_CODE</ogc:PropertyName> 
      <ogc:Literal>CED</ogc:Literal> 
     </ogc:PropertyIsEqualTo> 
     </ogc:Filter> 
     <MinScaleDenominator>65000</MinScaleDenominator> 
     <MaxScaleDenominator>150000</MaxScaleDenominator> 
     <PolygonSymbolizer> 
     <Fill> 
      <CssParameter name="fill">#228B22</CssParameter> 
      <CssParameter name="fill-opacity">1</CssParameter> 
     </Fill> 
     <Stroke> 
      <CssParameter name="stroke">#ADFF2F</CssParameter> 
      <CssParameter name="stroke-opacity"></CssParameter> 
      <CssParameter name="stroke-width">1.4</CssParameter> 
      <CssParameter name="stroke-linejoin">round</CssParameter> 
      <CssParameter name="stroke-linecap">round</CssParameter> 
     </Stroke> 
     </PolygonSymbolizer> 
     <TextSymbolizer> 
     <Label> 
      <ogc:PropertyName>NAME</ogc:PropertyName> 
     </Label> 
     <Font> 
      <CssParameter name="font-family">Sans-Serif</CssParameter> 
      <CssParameter name="font-style">normal</CssParameter> 
      <CssParameter name="font-size">20</CssParameter> 
      <CssParameter name="font-weight">bold</CssParameter> 
     </Font> 
     <Fill> 
      <CssParameter name="fill">#ADFF2F</CssParameter> 
     </Fill> 
     </TextSymbolizer> 
    </Rule> 
    <Rule> 
     <Name>Grass</Name> 
     <Title>Grass - 1:65,000 to 1:150,000</Title> 
     <Abstract>A Land Use style</Abstract> 
     <ogc:Filter> 
     <ogc:PropertyIsEqualTo> 
      <ogc:PropertyName>AREA_CODE</ogc:PropertyName> 
      <ogc:Literal>CED</ogc:Literal> 
     </ogc:PropertyIsEqualTo> 
     </ogc:Filter> 
     <MinScaleDenominator>65000</MinScaleDenominator> 
     <MaxScaleDenominator>150000</MaxScaleDenominator> 
     <PolygonSymbolizer> 
     <Fill> 
      <CssParameter name="fill">#90EE90</CssParameter> 
      <CssParameter name="fill-opacity">1</CssParameter> 
     </Fill> 
     <Stroke> 
      <CssParameter name="stroke">#6B8E23</CssParameter> 
      <CssParameter name="stroke-opacity"></CssParameter> 
      <CssParameter name="stroke-width">1.4</CssParameter> 
      <CssParameter name="stroke-linejoin">round</CssParameter> 
      <CssParameter name="stroke-linecap">round</CssParameter> 
     </Stroke> 
     </PolygonSymbolizer> 
     <TextSymbolizer> 
     <Label> 
      <ogc:PropertyName>NAME</ogc:PropertyName> 
     </Label> 
     <Font> 
      <CssParameter name="font-family">Sans-Serif</CssParameter> 
      <CssParameter name="font-style">normal</CssParameter> 
      <CssParameter name="font-size">20</CssParameter> 
      <CssParameter name="font-weight">bold</CssParameter> 
     </Font> 
     <Fill> 
      <CssParameter name="fill">#6B8E23</CssParameter> 
     </Fill> 
     </TextSymbolizer> 
    </Rule> 
    </FeatureTypeStyle> 
</UserStyle> 

<?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>Custom_Landuse</se:Name> 
<se:Description> 
    <se:Title>Custom_Landuse</se:Title> 
    <se:Abstract>A Land Use style</se:Abstract> 
</se:Description> 
<UserStyle> 
    <se:Name>County Electoral Division</se:Name> 
    <se:FeatureTypeStyle> 
    <se:Rule> 
     <se:Name>Woods</se:Name> 
     <ogc:Filter> 
     <ogc:PropertyIsEqualTo> 
      <ogc:PropertyName>AREA_CODE</ogc:PropertyName> 
      <ogc:Literal>CED</ogc:Literal> 
     </ogc:PropertyIsEqualTo> 
     </ogc:Filter> 
     <se:MinScaleDenominator>65000</se:MinScaleDenominator> 
     <se:MaxScaleDenominator>150000</se:MaxScaleDenominator> 
     <se:PolygonSymbolizer> 
     <se:Name>Woods</se:Name> 
     <se:Fill> 
      <se:SvgParameter name="fill">#228B22</se:SvgParameter> 
      <se:SvgParameter name="fill-opacity">0</se:SvgParameter> 
     </se:Fill> 
     <se:Stroke> 
      <se:SvgParameter name="stroke">#ADFF2F</se:SvgParameter> 
      <se:SvgParameter name="stroke-opacity"></se:SvgParameter> 
      <se:SvgParameter name="stroke-width">1.4</se:SvgParameter> 
      <se:SvgParameter name="stroke-linejoin">round</se:SvgParameter> 
      <se:SvgParameter name="stroke-linecap">round</se:SvgParameter> 
     </se:Stroke> 
     </se:PolygonSymbolizer> 
     <se:TextSymbolizer> 
     <se:Name>Woods</se:Name> 
     <se:Label> 
      <ogc:PropertyName>NAME</ogc:PropertyName> 
     </se:Label> 
     <se:Font> 
      <se:SvgParameter name="font-family">Sans-Serif</se:SvgParameter> 
      <se:SvgParameter name="font-style">normal</se:SvgParameter> 
      <se:SvgParameter name="font-size">20</se:SvgParameter> 
      <se:SvgParameter name="font-weight">bold</se:SvgParameter> 
     </se:Font> 
     <se:Fill> 
      <se:SvgParameter name="fill">#ADFF2F</se:SvgParameter> 
     </se:Fill> 
     </se:TextSymbolizer> 
    </se:Rule> 
    <se:Rule> 
     <se:Name>Grass</se:Name> 
     <ogc:Filter> 
     <ogc:PropertyIsEqualTo> 
      <ogc:PropertyName>AREA_CODE</ogc:PropertyName> 
      <ogc:Literal>CED</ogc:Literal> 
     </ogc:PropertyIsEqualTo> 
     </ogc:Filter> 
     <se:MinScaleDenominator>65000</se:MinScaleDenominator> 
     <se:MaxScaleDenominator>150000</se:MaxScaleDenominator> 
     <se:PolygonSymbolizer> 
     <se:Name>Grass</se:Name> 
     <se:Fill> 
      <se:SvgParameter name="fill">#90EE90</se:SvgParameter> 
      <se:SvgParameter name="fill-opacity">0</se:SvgParameter> 
     </se:Fill> 
     <se:Stroke> 
      <se:SvgParameter name="stroke">#6B8E23</se:SvgParameter> 
      <se:SvgParameter name="stroke-opacity"></se:SvgParameter> 
      <se:SvgParameter name="stroke-width">1.4</se:SvgParameter> 
      <se:SvgParameter name="stroke-linejoin">round</se:SvgParameter> 
      <se:SvgParameter name="stroke-linecap">round</se:SvgParameter> 
     </se:Stroke> 
     </se:PolygonSymbolizer> 
     <se:TextSymbolizer> 
     <se:Name>Grass</se:Name> 
     <se:Label> 
      <ogc:PropertyName>NAME</ogc:PropertyName> 
     </se:Label> 
     <se:Font> 
      <se:SvgParameter name="font-family">Sans-Serif</se:SvgParameter> 
      <se:SvgParameter name="font-style">normal</se:SvgParameter> 
      <se:SvgParameter name="font-size">20</se:SvgParameter> 
      <se:SvgParameter name="font-weight">bold</se:SvgParameter> 
     </se:Font> 
     <se:Fill> 
      <se:SvgParameter name="fill">#6B8E23</se:SvgParameter> 
     </se:Fill> 
     </se:TextSymbolizer> 
    </se:Rule> 
    </se:FeatureTypeStyle> 
</UserStyle> 

私は現在、このコード

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

# Run once per file 
StyledLayerDescriptor = ET.Element("StyledLayerDescriptor",version="1.0",) 
NamedLayer = ET.SubElement(StyledLayerDescriptor, "NamedLayer") 
Name = ET.SubElement(NamedLayer, "Name") 
Line_county_electoral_division_region" 
UserStyle = ET.SubElement(NamedLayer, "UserStyle") 
Name = ET.SubElement(UserStyle, "Name")" 
FeatureTypeStyle = ET.SubElement(UserStyle, "FeatureTypeStyle") 

# Run once per rule in file 
Rule = ET.SubElement(FeatureTypeStyle, "Rule") 
Name = ET.SubElement(Rule, "Name") 
Line_county_electoral_division_region" 
Title = ET.SubElement(Rule, "Title") 
Abstract = ET.SubElement(Rule, "Abstract") 
Filter = ET.SubElement(Rule, "Filter") 
PropertyIsEqualTo = ET.SubElement(Filter, "PropertyIsEqualTo") 
PropertyName = ET.SubElement(PropertyIsEqualTo, "PropertyName") 
Literal = ET.SubElement(PropertyIsEqualTo, "Literal") 
MinScaleDenominator = ET.SubElement(Rule, "MinScaleDenominator") 
MaxScaleDenominator = ET.SubElement(Rule, "MaxScaleDenominator") 
PolygonSymbolizer = ET.SubElement(Rule, "PolygonSymbolizer") 
Fill = ET.SubElement(PolygonSymbolizer, "Fill") 
Stroke = ET.SubElement(PolygonSymbolizer, "Stroke") 
TextSymbolizer = ET.SubElement(Rule, "PolygonSymbolizer") 
Label = ET.SubElement(TextSymbolizer, "Label") 
PropertyName = ET.SubElement(Label, "PropertyName") 
Front = ET.SubElement(TextSymbolizer, "Front") 
Fill = ET.SubElement(TextSymbolizer, "Fill") 

ET.SubElement(Fill, "CssParameter", name="fill") 
ET.SubElement(Fill, "CssParameter", name="fill-opacity") 
ET.SubElement(Stroke, "CssParameter", name="stroke") 
ET.SubElement(Stroke, "CssParameter", name="stroke-opacity") 
ET.SubElement(Stroke, "CssParameter", name="stroke-width") 
ET.SubElement(Stroke, "CssParameter", name="stroke-linejoin")" 
ET.SubElement(Stroke, "CssParameter", name="stroke-linecap") 
ET.SubElement(Front, "CssParameter", name="font-family") 
ET.SubElement(Front, "CssParameter", name="font-style") 
ET.SubElement(Front, "CssParameter", name="font-size") 
ET.SubElement(Front, "CssParameter", name="font-weight") 
ET.SubElement(Fill, "CssParameter", name="fill") 

Output = ET.ElementTree(StyledLayerDescriptor) 
Output.write("SLD_Test.xml", xml_declaration=True, encoding='UTF-8') 

parser = etree.XMLParser(remove_blank_text=True) 
tree = etree.parse("SLD_Test.xml", parser) 

tree.write("SLD_Test.xml", pretty_print=True) 

Tを有します彼のコードはprint xmlツリーを生成するために働いています

私は名前空間を変更するだけでなく、XMLの構造を再フォーマットしようとしています。たとえば、バージョン1.0は認識できませんが、データの一部が必要です。

私はpythonとXMLの両方を手に入れようとしているので、完全な解決策を探しているわけではありません。どんな助けも素晴らしいだろう!私は質問から集まる何から有用なチュートリアル

+0

[lxmlを使用してPythonでxmlから名前空間と接頭辞を削除する]の可能な複製(https://stackoverflow.com/questions/18159221/remove-namespace-and-prefix-from-xml-in-python-using-lxml) ) – stovfl

+0

それは似ていますが、私は再構築する必要があります(正しい言葉であれば)XMLと1から新しいファイルに情報をコピーします。しかし、それは確かに有用に見えます! –

答えて

0

にでもリンク、タスクは次のように変更することが含ま:同じローカル名を持つhttp://www.opengis.net/sld

  • 地図http://www.opengis.net/se要素
  • 変更CssParameter要素をSvgParameterに、属性
  • を維持することのxmlnsを削除します。= "http://www.opengis.net/gml" GML
  • UTF-8
  • にISO-8859-1を翻訳

ご質問にいくつか不足している単語がありますので、私はすべての規則を正確に理解していません。いずれにしても、SLD 1.1と1.0の違いを注意深く見直して、違いがないかどうかを確認してください。忘れないでください。入力ファイルで使用されていない相違点のルールを記述しないで、ちょっと騙すことができます。ここで

入力 ディレクトリから各XMLファイルを読み込み、短いPythonプログラム(sld11-10.py)は、出力ディレクトリを作成し、同じディレクトリ内の同じファイル名で同じ ディレクトリ構造を書き込み、 けどで、あります説明したように変換されたコンテンツ。ここで

#!/usr/bin/env python3 
from lxml import etree 
import os 
import sys 

sld10 = etree.XMLSchema(
    etree.parse("http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd")) 
sld11 = etree.XMLSchema(
    etree.parse("http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd")) 
transform = etree.XSLT(etree.parse("sld11-10.xsl")) 

def walk(sour_dir: str, dest_dir: str) -> None: 
    os.mkdir(dest_dir) 
    for item in os.listdir(sour_dir): 
     sour_path = os.path.join(sour_dir, item) 
     dest_path = os.path.join(dest_dir, item) 
     if os.path.isdir(sour_path): 
      walk(sour_path, dest_path) 
     else: 
      sour_doc = etree.parse(sour_path) 
      if not sld11.validate(sour_doc): 
       print(sour_path, sld11.error_log.last_error) 
      dest_doc = transform(sour_doc) 
      if not sld10.validate(dest_doc): 
       print(dest_path, sld10.error_log.last_error) 
      dest_doc.write(dest_path, 
       pretty_print=True, xml_declaration=True, encoding="UTF-8") 
    return None 

if __name__ == "__main__": 
    walk(sys.argv[1], sys.argv[2]) 

が参照XSLTファイルsld11-10.xslです:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
    xmlns:se="http://www.opengis.net/se" 
    xmlns:ogc="http://www.opengis.net/ogc" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:sld="http://www.opengis.net/sld" 
    exclude-result-prefixes="sld se"> 

    <xsl:output encoding="UTF-8"/> 

    <!-- 
    Chanage the version and the schemaLocation values 
    --> 

    <xsl:template match="/sld:StyledLayerDescriptor"> 
    <StyledLayerDescriptor xmlns="http://www.opengis.net/sld" 
     xmlns:ogc="http://www.opengis.net/ogc" 
     xmlns:xlink="http://www.w3.org/1999/xlink" 
     xmlns:gml="http://www.opengis.net/gml"> 
     <xsl:apply-templates select="@*"/> 
     <xsl:attribute name="version">1.0.0</xsl:attribute> 
     <xsl:attribute name="xsi:schemaLocation" 
     namespace="http://www.w3.org/2001/XMLSchema-instance"> 
     <xsl:text>http://www.opengis.net/sld </xsl:text> 
     <xsl:text>http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd</xsl:text> 
     </xsl:attribute> 
     <xsl:apply-templates/> 
    </StyledLayerDescriptor> 
    </xsl:template> 

    <!-- 
    Map SvgParameter elements in the http://www.opengis.net/se namespace 
    to CssParameter in the http://www.opengis.net/sld namespace 
    --> 

    <xsl:template match="se:SvgParameter"> 
    <xsl:element name="CssParameter" namespace="http://www.opengis.net/sld"> 
     <xsl:apply-templates select="@*"/> 
     <xsl:apply-templates/> 
    </xsl:element> 
    </xsl:template> 

    <!-- 
    Map remaining http://www.opengis.net/se elements and attributes 
    to the http://www.opengis.net/sld namespace 
    --> 

    <xsl:template match="se:*"> 
    <xsl:element name="{local-name()}" namespace="http://www.opengis.net/sld"> 
     <xsl:apply-templates select="@*"/> 
     <xsl:apply-templates/> 
    </xsl:element> 
    </xsl:template> 

    <!-- 
    Preserve all other elements and attributes 
    --> 

    <xsl:template match="*|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:apply-templates/> 
    </xsl:copy> 
    </xsl:template> 

    <!-- 
    Preserve processing instructuions and comments 
    --> 

    <xsl:template match="processing-instruction()|comment()"> 
    <xsl:copy>.</xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

if name == "main": walk(sys.argv[1], sys.argv[2]部分は、コマンドラインからプログラムを実行すると 、それはとして最初 2つのコマンドラインパラメータを使用することを意味します歩行ルーチンへの入力。例えば、 はあなた デスクトップにsld11-10.pysld11-10.xsl、およびinput_directoryを持っていると言う、その後、input_directoryあなたはoutput_directoryというディレクトリを持っていない、あなた が実行できると仮定すると、そのようなこの

などのファイルが含まれていると言います

:プログラムこの

sld11-10.py input_directory output_directory 

のようなファイルには、次のような構造でoutput_direcoryを作成します。

output_directory 
    file1.xml 
    file2.xml 
    subdirectory 
    file3.xml 

input_directoryoutput_directoryの違いはoutput_directoryで XMLファイルは、XSLT変換を経てきたということです。 また、変換中に、XMLファイルの 妥当性に関する情報(SLD 1.0とSLD 1.1の両方)が、処理中に画面 に書き込まれることにも注意してください。

+0

こんにちは!ありがとう、私はこれが解決策かもしれないと思います。私はちょうどそれが働く方法を戦うことを試みている。私はそれがほとんどのこのセクションをバーで働いていると思う。 if __name__ == "__main__": walk(sys.argv [1]、sys.argv [2]) –

+0

答えが更新され、 'if __name__ ==" __main __ "'部分の説明が追加されました。 – rcrews

関連する問題