Python将YAML转换为XML

4 投票
1 回答
6357 浏览
提问于 2025-04-16 14:37

1. 背景

我们有一个应用程序,它依赖于几个XML配置文件。这些XML文件定义了一些内容,比如连接设置、轮询频率、多个用户账户(使用XSD嵌套类型/序列)等等。

我有这些XML文件的XSD模式。下面是一个小片段:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="FooExch"  type="CConfigFooType"/>

<xs:complexType name="CConfigFooType">
  <xs:sequence>
    <xs:element name="_appID" type="xs:string"/>
    ...
    <xs:element name="_logins" type="FooLoginsType" maxOccurs="unbounded"/>
    <xs:element name="_passwords" type="FooPasswordType" maxOccurs="unbounded"/>
    ...
  </xs:sequence>
</xs:complexType>

<xs:complexType name="FooLoginsType">
  <xs:sequence>
    <xs:element name="_name" type="xs:string"/>
    <xs:element name="_adapterID" type="xs:int"/>
    <xs:element name="_FooLogins" type="FooAccountType" maxOccurs="unbounded"/>
  </xs:sequence>
</xs:complexType>

<xs:complexType name="FooAccountType">
  <xs:sequence>
    <xs:element name="_FooAccount" type="xs:string"/>
    <xs:element name="_mktFeed" type="xs:int"/>
  </xs:sequence>
</xs:complexType>

<xs:complexType name="FooPasswordType">
  <xs:sequence>
    <xs:element name="_name" type="xs:string"/>
    <xs:element name="_password" type="xs:string"/>
  </xs:sequence>
</xs:complexType>

</xs:schema>

2. 目标

我们的目标是让用户更容易调整或添加设置。

我想提供一个脚本,它可以读取一个YAML文件,并根据XSD生成一个XML配置文件(对于缺失的值,可能会使用default.yaml文件中的默认值)。

我们还需要能够将一个YAML文件“附加”到XML中——也就是说,用户可以有一个只定义他们用户账户的YAML文件,我们会把这个账户导入到现有XML文件的用户账户列表中。

3. 方法

到目前为止,我正在使用GenerateDS(http://www.rexx.com/~dkuhlman/generateDS.html)从XSD生成一个Python包装器。

通过这个工具,我可以创建一个表示XML模式的Python对象,然后将其导出为XML。

现在的问题是,如何将YAML转换为XML?

理想情况下,我希望有一个通用的循环,可以遍历每个值,并将其添加到Python表示中。

我最初的想法是使用getattr(config_wrapper, "yaml_name") = yaml_value,然后遍历YAML中的每个值,捕获AttributeError,以处理那些不在XSD中的值。

我的第一个问题是,这种方法是否存在问题,或者是否有更Pythonic/更简洁的方式来实现?有没有更聪明的方法来解决这个问题?

我的第二个问题是——根据上面的XSD部分,我们需要有嵌套的登录信息,包括用户名和密码。我知道PyYAML提供了嵌套集合,但我仍然不太确定这将如何与GenerateDS结合,或者我该如何使其足够通用,以便可靠地工作。

谢谢,
Victor

1 个回答

1

我建议不要使用XSD,这听起来像是为了很小的好处而搞很多繁琐的手续。

  1. 先创建一个YAML文件,结构要和XML文件一样。
  2. 用pyyaml把文件加载进来。
  3. 遍历加载的结果,使用elementtree创建一个相应的树状结构。
  4. 把这个树状结构写入XML文件。
  5. 把XML文件发送到系统,如果系统报错,就修正YAML文件,然后回到第2步。

撰写回答