zoukankan      html  css  js  c++  java
  • Python之处理svg文件中的style属性

    功能介绍

    主要是把svg图片中的style属性内部的值,放到外部。

    demo.xml

    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" xml:space="preserve"
         preserveAspectRatio="none"><defs></defs>
        <g transform="matrix(0.439528 0 0 0.439528 330.719764 171.306754)" id="图层_1">
    <path style="stroke: none; stroke- 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;"
          transform=" translate(-341.275, -21.812)" d="M 682.55 43.624 H 0 V 0 h 682.55 V 43.624 z" stroke-linecap="round"/>
    </g>
    </svg>
    

    正则实现

    from xml.dom import minidom
    import re
    
    def update_xml(xml_file_path):
        """
        功能:style属性移外部
        :param xml_file_path: xml 文件路径
        :return: 返回 xml 文件
        """
        dom = minidom.parse(xml_file_path)
        root = dom.documentElement
        svg_dom = root.toxml()
        styles = re.findall('style="[^"]+"', svg_dom)
        try:
            for style in styles:
                data_list = []
                attrs = re.findall('([w-]+):s*([^;]+)', style)
                name, value = attrs[-1]
                sub_value = value.replace(""", "")
                attrs[-1] = (name, sub_value)
                for attr in attrs:
                    key, value = attr
                    if not value in ['butt']:
                        data_list.append(key + '="' + value + '"')
                svg_dom = svg_dom.replace(style, " ".join(data_list))
            with open(xml_file_path, 'w', encoding='utf-8') as f:
                f.write(svg_dom)
            return xml_file_path
        except Exception as e:
            print(f'update_xml : {e}')
    
    
    if __name__ == '__main__':
        update_xml('demo.xml')
    

    更新后的demo.xml

    <svg preserveAspectRatio="none" version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
         xmlns:xlink="http://www.w3.org/1999/xlink"><defs/>
        <g id="图层_1" transform="matrix(0.439528 0 0 0.439528 330.719764 171.306754)">
    <path d="M 682.55 43.624 H 0 V 0 h 682.55 V 43.624 z" stroke-linecap="round" stroke="none" stroke-width="1"
          stroke-dasharray="none" stroke-dashoffset="0" stroke-linejoin="miter" stroke-miterlimit="4" fill="rgb(0,0,0)"
          fill-rule="nonzero" opacity="1" transform=" translate(-341.275, -21.812)"/>
    </g>
    </svg>
    

    注意

    • svg 标签可能不及这几个标签的。可能会有多层标签里都有style内部属性。

    由于本人正则不怎么会,所以在处理attrs = re.findall('([w-]+):s*([^;]+)', style)的时候,出现了attrs这个列表里最后一对元组里的第二个值是有一个双引号的"。
    所以就采用了这种方式:

    name, value = attrs[-1]
    sub_value = value.replace(""", "")
    

    进行处理。如果您有更好的处理方式请在评论区告诉我或者私信也行,谢谢。

    更新实现的功能

    def update_xml(xml_file_path):
        dom = minidom.parse(xml_file_path)
        root = dom.documentElement
        root = extract_change_style(root)
        with open(xml_file_path, 'w', encoding='utf-8') as f:
            f.write(root.toxml())
        return xml_file_path
    
    
    def extract_change_style(node):
        """
        处理 xml 内部的 style
        :param node:
        :return:
        """
        for i in range(0, node.attributes.length):
            attr = node.attributes.item(i)
            attr_name = attr.name
            if attr_name == 'style':
                attr_value = attr.value
                sheet = cssutils.parseString("#rule{" + attr_value + "}")
    
                for rule in sheet.cssRules:
                    if rule.type == rule.STYLE_RULE:
                        for property in rule.style:
                            if property.name in ['fill', 'stroke', 'stop-color']:
                                if not property.value in ['none', 'transport']:
                                    node.setAttribute(property.name, property.value)
                                    rule.style.removeProperty(property.name)
    
                text = sheet.cssText
                text = text.decode('utf-8').replace("#rule {", "").replace("}", "").replace("
    ", "").replace("
    ",
                                                                                                              "").replace(
                    "    ", "")
                node.setAttribute("style", text)
    
        for i, child in enumerate(node.childNodes):
            if child.nodeType == 1:
                temp = extract_change_style(child)
                node.childNodes[i] = temp
        return node
    

    上面的功能是实现:提取style里的fill,stroke, stop-color,并且值不为 none 或者 transport才会被提取到外部中。

  • 相关阅读:
    linux下的grep命令
    linux下的ps命令
    删除eclipse无效的工作空间路径
    js中 var functionName = function() {} 和 function functionName() {} 两种函数声明的区别
    javascript中的function 函数名(){} 和 函数名:function(){}有什么不同
    Python之路-python(css布局、JavaScript)
    Python之路-python(css、JavaScript)
    Python之路-python(html、css)
    Python之路-python(堡垒机)
    Python之路-python(mysql介绍和安装、pymysql、ORM sqlachemy)
  • 原文地址:https://www.cnblogs.com/zhenzi0322/p/14075285.html
Copyright © 2011-2022 走看看