需要使用Python生成包含xml内容(而不仅仅是文本)的子元素

需要使用Python生成包含xml内容(而不仅仅是文本)的子元素,python,xml,Python,Xml,我不熟悉python和xml。我正在使用python生成一个xml文件。该xml文件将根据一些输入配置文件每天生成。 在xml文件中创建子元素时需要一些帮助。因为它不是在正确的父元素下生成的。请输入当前和所需的输出 我有一个包装器python脚本和生成器python脚本。 发电机 包装程序Py脚本: 发电机Py sript: from xml.etree import ElementTree from xml.etree.ElementTree import Element from xml.

我不熟悉python和xml。我正在使用python生成一个xml文件。该xml文件将根据一些输入配置文件每天生成。 在xml文件中创建子元素时需要一些帮助。因为它不是在正确的父元素下生成的。请输入当前和所需的输出

我有一个包装器python脚本和生成器python脚本。 发电机

包装程序Py脚本:
发电机Py sript:

from xml.etree import ElementTree
from xml.etree.ElementTree import Element
from xml.etree.ElementTree import SubElement
from xml.dom import minidom

class Workflow:
    def __init__(self, name, namespace=WF_NAMESPACE):
        self.xml = Element('workflow-app')
        self.action_counter = 0
    def insert_action(self, action):

class Action:
    def __init__(self):
        self.xml = Element('action')
        self._position = 0

class SubWFAction(Action):
    def __init__(self):
        Action.__init__(self)
        action_type = 'sub-workflow'
        self.xml.set('name', action_type)
        this_node = Element(action_type)
        self.xml.insert(self._position, this_node)
        self.sub_workflow = self.xml[self._position]

    def app_path(self, inner_text):
        node = SubElement(self.sub_workflow, 'app-path')
        cpnode = SubElement(self.sub_workflow, 'propagate-configuration')
        node.text = inner_text

    def configsec(self, inp_list):
        configuration = SubElement(self.sub_workflow, 'configuration')
        proptext = [self.property(prop[0], prop[1]) for prop in inp_list]
        return proptext

    def property(self, key, value):
        property = SubElement(self.xml,'property')
        name = SubElement(property,'name')
        name.text = key
        val = SubElement(property,'value')
        val.text = value
电流输出:

<?xml version="1.0" encoding="UTF-8"?>
<workflow-app name="wf_ntflx_genr" xmlns="uri:oozie:workflow:0.5">
    <start to="sub-workflow"/>
    <action name="sub-workflow">
        <sub-workflow>
            <app-path>
              /ntflx/tesfile.dat
            </app-path>
            <propagate-configuration/>
            <configuration/>
        </sub-workflow>
        <configuration/>
        <ok to="end"/>
        <error to="kill"/>
        <property>
            <name>
                catg
            </name>
            <value>
                first
            </value>
        </property>
    </action>

/ntflx/tesfile.dat
catg
第一
期望输出:

<?xml version="1.0" encoding="UTF-8"?>
<workflow-app name="wf_ntflx_genr" xmlns="uri:oozie:workflow:0.5">
    <start to="sub-workflow"/>
    <action name="sub-workflow">
        <sub-workflow>
            <app-path>
              /ntflx/tesfile.dat
            </app-path>
            <propagate-configuration/>
            <configuration>
                <property>
                    <name>
                        catg
                    </name>
                    <value>
                        first
                    </value>
                </property>
            </configuration>
        </sub-workflow>
        <ok to="end"/>
        <error to="kill"/>
    </action>

/ntflx/tesfile.dat
catg
第一
请帮忙

您希望
位于
之下,因此需要向
子元素提供正确的元素。你可以用几种方法来做,我不确定哪种方法在你的总体设计中最有意义。但一种方法是跟踪当前配置,并让
属性
将其数据放入其中。我注意到代码中还有一个潜在的bug

def configsec(self, inp_list):
    # Changed: Remember the current configuration element so that
    # properties can be applied
    self.configuration = SubElement(self.sub_workflow, 'configuration')
    # TODO: this creates properties in the xml but since `property` 
    # returns `None` you return a list of `None`s here.
    proptext = [self.property(prop[0], prop[1]) for prop in inp_list]
    return proptext

def property(self, key, value):
    # changed: set the property element on the current configuration
    property = SubElement(self.configuration,'property')
    name = SubElement(property,'name')
    name.text = key
    val = SubElement(property,'value')
    val.text = value
您希望
位于
下,因此需要向
子元素提供正确的元素。你可以用几种方法来做,我不确定哪种方法在你的总体设计中最有意义。但一种方法是跟踪当前配置,并让
属性
将其数据放入其中。我注意到代码中还有一个潜在的bug

def configsec(self, inp_list):
    # Changed: Remember the current configuration element so that
    # properties can be applied
    self.configuration = SubElement(self.sub_workflow, 'configuration')
    # TODO: this creates properties in the xml but since `property` 
    # returns `None` you return a list of `None`s here.
    proptext = [self.property(prop[0], prop[1]) for prop in inp_list]
    return proptext

def property(self, key, value):
    # changed: set the property element on the current configuration
    property = SubElement(self.configuration,'property')
    name = SubElement(property,'name')
    name.text = key
    val = SubElement(property,'value')
    val.text = value

谢谢你。这个改变解决了我的问题。我想知道您注意到的错误是什么。您使用
property=SubElement(self.xml,'property')
创建了
元素,但是
self.xml
没有引用
元素。我将为这些更改添加一些注释。谢谢tdelaney。这个改变解决了我的问题。我想知道您注意到的错误是什么。您使用
property=SubElement(self.xml,'property')
创建了
元素,但是
self.xml
没有引用
元素。我将为这些更改添加一些注释。