Lxml读写XML字符

一、修改xml文件的节点文本、节点属性、删除节点

复制代码
from lxml import etree

将string转换成python对象
e1 = etree.XML(xml_content)

读取xml字符串中的指定节点文本与属性
a1 = e1.xpath("//SPEC_LIST/text()")   # 节点文本
a1 = e1.xpath("//SPEC_LIST/@class")   # 节点属性

添加子节点
obj = e1.xpath("//SPEC_LIST")[0]      # 获取节点
spec = etree.SubElement(obj, "SPEC")  # 添加子节点

修改节点文本
obj = e1.xpath("//SPEC_LIST")[0]      # 获取节点
obj.text = '文本'                      # 修改节点文本

修改节点属性
obj = e1.xpath("//SPEC_LIST")[0]      # 获取节点
obj.attrib['cpu'] = "8"               # 设置节点属性,attrib属性是一个字典

将python对象转换成string
content = etree.tounicode(e1)         # unicode
content = etree.tostring(e1)          # bytes
复制代码

 

例子:

复制代码
from lxml import etree

# xml文件
""" <breakfast> <food> <name>apple</name> <description file='/etc/libvirt/qemu/apple.xml'></description> <mac address='123456789'></mac> </food> </breakfast> """ xml_content = "<breakfast><food><name>apple</name><description file='/etc/libvirt/qemu/apple.xml'></description><mac address='123456789'></mac></food></breakfast>" """ 实现: 修改name为tomato 修改/etc/libvirt/qemu/apple.xml为 /usr/bin/tomato.xml 删除mac这一行 """ config = etree.XML(xml_content) name = config.xpath("//name")[0] # <Element name at 0x256fff06108> description = config.xpath("//description")[0] # <Element description at 0x256fff06148> food = config.xpath("//food")[0] # <Element food at 0x256fff061c8> mac = config.xpath("//mac")[0] # <Element mac at 0x256fff06208> print(dir(name)) """ ['__bool__', '__class__', '__contains__', '__copy__', '__deepcopy__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', '_init', 'addnext', 'addprevious', 'append', 'attrib', 'base', 'clear', 'cssselect', 'extend', 'find', 'findall', 'findtext', 'get', 'getchildren', 'getiterator', 'getnext', 'getparent', 'getprevious', 'getroottree', 'index', 'insert', 'items', 'iter', 'iterancestors', 'iterchildren', 'iterdescendants', 'iterfind', 'itersiblings', 'itertext', 'keys', 'makeelement', 'nsmap', 'prefix', 'remove', 'replace', 'set', 'sourceline', 'tag', 'tail', 'text', 'values', 'xpath'] """ name.text = 'tomato' description.attrib['file'] = '/usr/bin/tomato.xml' food.remove(mac) xml_content = etree.tounicode(config) print(xml_content) """ <breakfast> <food> <name>tomato</name> <description file="/usr/bin/tomato.xml"/> </food> </breakfast> """
复制代码

 

 

二、案例

 

html页面布局

 

js渲染页面

 

 编写js:输入值

View Code

 

 编写js:获取值保存到数据库中:

复制代码
var params_list = [];

// 构造参数Map>> Array (动态参数)
$('#param_se option').each(function () {
   // 构造单个参数信息
    var txt_param_list = $(this).text().split(":");
    var val_param = $(this).prop("value");
    var param_id = $(this).attr("param_id");
    var param_dict = {
           "param_name": txt_param_list[0],
            "variable_name": val_param,
            "param_value": txt_param_list[1],
            "param_id": param_id
      };
     params_list.push(param_dict)
});

console.log(params_list)
复制代码

 

复制代码
from lxml import etree
root = etree.Element("root")
config = [{'param_name': '主机参数2', 'variable_name': 'hostname2', 'param_value': 'hostname_value2'},
{'param_name': '主机参数1', 'variable_name': 'hostname1', 'param_value': 'hostname_value1'}]
# 动态参数
for c_config in config:
    param_node = etree.SubElement(root, "param")
    param_node.attrib["param_name"] = c_config["param_name"].strip()
    param_node.attrib["variable_name"] = c_config["variable_name"].strip()
    param_node.attrib["param_value"] = c_config["param_value"].strip()
config = etree.tounicode(root)
print(config)
"""
<root><param param_name="主机参数2" variable_name="hostname2" param_value="hostname_value2"/>
<param param_name="主机参数1" variable_name="hostname1" param_value="hostname_value1"/></root>
"""
复制代码

 

数据库获取通过etree模块展示到前端:

 

复制代码
from lxml import etree

config = '<root><param param_name="主机参数2" variable_name="hostname2" param_value="hostname_value2"/><param param_name="主机参数1" variable_name="hostname1" param_value="hostname_value1"/></root>'
param_list = []
pre_config = "<root></root>"

if config:
    config = etree.XML(config)
else:
    config = etree.XML(pre_config)
param_nodes = config.xpath("//param")
print(param_nodes)  # [<Element param at 0x25f8e5ab208>, <Element param at 0x25f8e5ab188>]
for pn in param_nodes:
    print(pn.attrib)
    """
    {'param_name': '主机参数2', 'variable_name': 'hostname2', 'param_value': 'hostname_value2'}
    {'param_name': '主机参数1', 'variable_name': 'hostname1', 'param_value': 'hostname_value1'}
    """
    param_list.append({
        "param_name": pn.attrib.get("param_name", ""),
        "variable_name": pn.attrib.get("variable_name", ""),
        "param_value": pn.attrib.get("param_value", ""),
    })

print(param_list)
"""
[{'param_name': '主机参数2', 'variable_name': 'hostname2', 'param_value': 'hostname_value2'},
{'param_name': '主机参数1', 'variable_name': 'hostname1', 'param_value': 'hostname_value1'}]
"""
复制代码

 

re正则:

param_type = 'HOST'
content = '#!/bin/bash echo "((hostname1))"echo "((hostname2))"' 

com = re.compile("\(\((.*?)\)\)")
variable_list = com.findall(content)
print(variable_list)   #['hostname1', 'hostname2']

 

复制代码
data = []
for i in variable_list:
    for j in param_list:
        if i.strip() == j["variable_name"]:
            data.append({
                "param_name": j["param_name"],
                "variable_name": j["variable_name"],
                "param_value": j["param_value"],
                "type": "SCRIPT"
            })
            break

print(data)
"""
[{'param_name': '主机参数1', 'variable_name': 'hostname1', 'param_value': 'hostname_value1', 'type': 'SCRIPT'}, 
{'param_name': '主机参数2', 'variable_name': 'hostname2', 'param_value': 'hostname_value2', 'type': 'SCRIPT'}]
"""
复制代码

 

posted @   困了就睡觉觉  Views(926)  Comments(0Edit  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
历史上的今天:
2019-07-01 Postman的使用
2019-07-01 APIView源码与Request源码分析
2019-07-01 RESTful规范与django编写restful接口
2019-07-01 CBV源码解析
2019-07-01 Drf简介
点击右上角即可分享
微信分享提示