lxml 基于另一个 XML 文件递归创建 XML 文件

lxml Create XML file recursively based on another XML File

我的目标是基于另一个 XML 文件递归创建一个 XML 文件。
示例输入数据如下(原始文件约为 10MB)

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Picture Name="Template">
  <Children>
    <Shape Name="GroupLevel" ClassName="Group">
      <Properties>
        <Property Name="Property1" Value="Value1" />
        <Property Name="Property2" Value="Value2" />
        <Property Name="Property3" Value="Value3" />
      </Properties>
      <ContainedObjects>
        <Shape Name="Group1" ClassName="Group">
          <Properties>
            <Property Name="Property1" Value="Value1" />
            <Property Name="Property2" Value="Value2" />
            <Property Name="Property3" Value="Value3" />
          </Properties>
          <ContainedObjects>
            <Shape Name="Glue123" ClassName="Text" />
            <Shape Name="Variable1" ClassName="Variable" />
            <Shape Name="Variable2" ClassName="Variable" />
            <Shape Name="Variable3" ClassName="Variable" />
            <Shape Name="Group2" ClassName="Group">
              <Properties>
                <Property Name="Property1" Value="Value1" />
                <Property Name="Property2" Value="Value2" />
                <Property Name="Property3" Value="Value3" />
              </Properties>
              <ContainedObjects>
                <Shape Name="Group3" ClassName="RoundRect" />
              </ContainedObjects>
            </Shape>
          </ContainedObjects>
        </Shape>
      </ContainedObjects>
    </Shape>
  </Children>
</Picture>

  1. 需要在 Child 标签内循环。在循环期间,如果我找到 Shape 标签,其父级为 Children,则在空白根目录中创建一个具有该标签名称的节点。
  2. 忽略属性/属性 节点
  3. 如果我找到父级为 ContainedObjects 的形状标签,请在保持深度的同时创建节点 ContainedObjects,在该 ContainedObjects 节点内添加 Shape 标签。
  4. 实际操作涉及根据每个形状标签创建一组不同的节点,这将在稍后阶段完成。
    目前,我卡在递归循环中。

<Children>
  <Shape Name="GroupLevel" ClassName="Group">
    <ContainedObjects>
      <Shape Name="Group1" ClassName="Group">
        <ContainedObjects>
          <Shape Name="Glue123" ClassName="Text" />
          <Shape Name="Variable1" ClassName="Variable" />
          <Shape Name="Variable2" ClassName="Variable" />
          <Shape Name="Variable3" ClassName="Variable" />
          <Shape Name="Group2" ClassName="Group">
            <ContainedObjects>
              <Shape Name="Group3" ClassName="RoundRect" />
            </ContainedObjects>
          </Shape>
        </ContainedObjects>
      </Shape>
    </ContainedObjects>
  </Shape>
</Children>

问题代码 - 这不起作用,我尝试递归循环,但它不包含对象的 depth/nesting。请分享任何指针。

def RecurseXML(Data_Tree):
    for Children in Data_Tree.iterchildren():
        if Children.tag == "Shape":
            Owner       = Children.getparent().tag
            Owner       = etree.SubElement(Root_Child,Owner)
            SomeValue   = etree.SubElement(Owner,Children.tag,attrib={"Name":Children.attrib['Name']})
            Root_Child.append(SomeValue)
        if len(Children) > 0:
            RecurseXML(Children)

XSLT 擅长于此:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>
  
  <xsl:template match="*">
    <xsl:apply-templates/>
  </xsl:template>

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

</xsl:stylesheet>

lxml 允许您 运行 XSLT。