Python将YAML转换为XML
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 个回答
我建议不要使用XSD,这听起来像是为了很小的好处而搞很多繁琐的手续。
- 先创建一个YAML文件,结构要和XML文件一样。
- 用pyyaml把文件加载进来。
- 遍历加载的结果,使用elementtree创建一个相应的树状结构。
- 把这个树状结构写入XML文件。
- 把XML文件发送到系统,如果系统报错,就修正YAML文件,然后回到第2步。