通过python将SLD从1.1转换为1.0

2024-05-20 01:32:32 发布

您现在位置:Python中文网/ 问答频道 /正文

目前,我试图通过编写python脚本将SLD(一种XML类型)从一个版本转换为另一个版本。近两个星期来,我一直在努力工作,但进展甚微。 我对python还不熟悉,如果有任何建议,我将不胜感激!
基本上,我需要把这个…。在

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

在 在

在这件事上

^{pr2}$

在 在

我现在有这个代码

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)

此代码用于生成打印xml树

我不只是想更改名称空间,而是要重新格式化xml的结构,例如,版本1.0无法识别,但有些数据是在下面需要的。在

我并不是在寻找完整的解决方案,因为我正在努力掌握python和XML。任何帮助都太好了!甚至可以链接到有用的教程


Tags: nameogcstrokerulefilletfontsubelement
1条回答
网友
1楼 · 发布于 2024-05-20 01:32:32

根据我从问题中收集到的信息,该任务包括进行以下更改:

你的问题有些漏词,所以我不完全理解所有的规则。在任何情况下,您都需要仔细检查sld1.1和1.0之间的差异,以确保您有针对这些差异的规则。别忘了,你可以通过不为输入文件不使用的差异编写规则来作弊。在

下面是一个简短的Python程序(sld11-10.py),它从输入中读取每个XML文件 目录,然后创建一个输出目录并写入一个相同的 同一目录中具有相同文件名的目录结构, 但内容如所述进行了转换。在

#!/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

^{pr2}$

if name == "main": walk(sys.argv[1], sys.argv[2]部分的意思是 当您从命令行运行程序时,它将使用第一个 两个命令行参数作为walk例程的输入。例如, 假设您的 桌面,然后说input_directory包含这样的文件

input_directory
  file1.xml
  file2.xml
  subdirectory
    file3.xml

然后,假设没有名为output_directory的目录,则 可以像这样运行文件

sld11-10.py input_directory output_directory

程序将使用以下结构创建output_direcory

output_directory
  file1.xml
  file2.xml
  subdirectory
    file3.xml

input_directory和{}之间的区别是 output_directory中的XML文件将经过XSLT转换。 另外,请注意,在转换过程中,有关 将写入SLD 1.0和SLD 1.1的XML文件的有效性 过程中的屏幕。在

相关问题 更多 >