是否有可能获得在XSD中定义的XML节点的类型?

时间:2011-01-25 23:02:08

标签: python xml xsd xsd-validation

我在python中解析XML。我有一个XSD架构来验证XML。我可以获取我在XSD中定义的XML特定节点的类型吗?

例如,我的XML(小部分)是

<deviceDescription>
  <wakeupNote>
    <lang xml:lang="ru">Русский</lang>
    <lang xml:lang="en">English</lang>
  </wakeupNote> 
</deviceDescription>

我的XSD(再一次是它的一小部分):

<xsd:element name="deviceDescription" type="zwv:deviceDescription" minOccurs="0"/>

<xsd:complexType name="deviceDescription">
  <xsd:sequence>
    <xsd:element name="wakeupNote" type="zwv:description" minOccurs="0">
      <xsd:unique name="langDescrUnique">
        <xsd:selector xpath="zwv:lang"/> 
        <xsd:field xpath="@xml:lang"/>  
      </xsd:unique>
    </xsd:element> 
  </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="description">
  <xsd:sequence>
    <xsd:element name="lang" maxOccurs="unbounded">
      <xsd:complexType>
        <xsd:simpleContent>
          <xsd:extension base="xsd:string">
            <xsd:attribute ref="xml:lang" use="required"/>
          </xsd:extension>
        </xsd:simpleContent>
      </xsd:complexType>
    </xsd:element>
  </xsd:sequence> 
</xsd:complexType>

在解析期间,我想知道我的标签 wakeupNote 在XSD中被定义为 complexType zwv:description 。怎么做(在python中)?

我需要什么?假设我有很多这些XML,我想检查所有这些XML都填充了英语语言的字段。很容易检查<lang xml:lang="en"></lang>是否为空,但是根本不允许指定此标记。

因此,我们的想法是获取所有可能包含语言描述的标记,并检查<lang>标记是否存在,并且 en 的内容非空。

UPD

因为在验证期间我的XML是根据XSD进行检查的,所以验证引擎知道所有节点的类型。 7个月前我有一个类似的问题仍然没有答案。他们是相关的,imho。 Validating and filling default values in XML based on XSD in Python

2 个答案:

答案 0 :(得分:0)

如果问题是:如何找到给定XML节点的类型名称? 答案是使用xpath in python进行查找。在xsd上运行的xpath将是

//element[@name='wakeupNote']/@type

这应该返回zwv:description。如果它返回两种类型,则必须从根

开始
/root/foo/wakeupNote (type A)
/root/bar/wakeupNote (type B)

从根本上走下去将是乏味的。你必须寻找自治和命名类型。

如果问题是:如何查找给定类型的所有XML节点? 如果架构经常更改,则可以在使用上述方法解析每个节点时测试每个节点的类型。

如果架构众所周知,已修复,并且您正在寻找的节点可以通过XPATH找到,那么您可以测试每个节点。

//@xml:lang='en'

然后使用python检查每个的长度。

在稳定架构的情况下,您可以编写第二个XSD来强制执行您要查找的条件。

答案 1 :(得分:0)

你是对的,验证者必须知道它验证的所有元素和属性的类型关联,并且验证者因此能够提供对该信息的访问。

然而,无论好坏,调用者和验证者之间的API以及调用者可用的验证相关信息的选择都是完全实现定义的。一些验证器(Xerces J是一个值得注意的例子)提供了非常全面的验证信息;别人不这样做。

在不知道您使用的验证器的情况下,没有人能够肯定地告诉您您所寻找的类型信息是否可用。由于您正在调用验证器,因此必须有API;如果通过API可以获得类型关联,那么文档可能会这样说。如果API不提供对它的访问,则可能是因为底层模式验证器不提供对信息的访问,或者可能是因为API的创建者没有看到该点;你的工作(如果你想进一步追求这一点)将是找出哪些是这种情况,然后试图说服有关各方提供信息是有用的。

如果您没有通过API访问信息的运气,您可以使用David W的另一个答案中提到的更复杂的方法来帮助自己.XSD架构的属性是管理类型任何元素严格地来自验证根中该元素的路径的函数,因此原则上(如果在实践中有点繁琐)很难直接识别文档实例中的任何元素,它的管理类型是什么如果针对特定架构验证了文档实例。例如,对于您提到的情况,可以直接判断给定的wakeupNotedeviceDescription还是otherElement作为祖先,或者wakeupNote是哪个更近的祖先?具有两者,并根据该知识推断出适当的管理类型定义。

以这种方式帮助自己可能需要一些非常重要的工作。如果有通用工具来计算这些信息并以各种形式访问它会有所帮助,但是如果有这样的话,我不知道它们。 (我确实知道可以收费的人可以建立这样的工具。)所以如果我是你,我会先尝试通过API获取信息。