【问题标题】:XSD to validate XML with different sequence elements based on parent attributeXSD 使用基于父属性的不同序列元素来验证 XML
【发布时间】:2021-06-28 15:08:26
【问题描述】:

我查看了有关 stackoverflow 的其他提及,但没有真正看到任何适合我正在寻找的内容。

我已经使用 JAXB 生成了一个 .xsd,但不幸的是它不是很好,所以当我意识到有些东西似乎与我所遵循的其他模式的逻辑并不匹配时,我手动创建了一个。

最好将其显示为代码,而不是冗长的描述。我有许多带有重复元素的 xml 文档,这些元素根据它们的父 (ItemGroup) 元素 id 不同。其中一些 id 是重复的(如图所示),一些只会出现一次(它们以 0 结尾或者是 DocDetails 的一部分)。此外,特定“id”的元素始终是相同的元素列表。

在示例中,以 0 结尾的元素只出现一次,以 1 结尾的元素是重复元素(虽然通常不超过 2),以 2 结尾的元素重复任意次数。这个后缀编号是人为的让它变得明显,但相同的固定 ItemGroup id 有 1 或重复的元素。

<?xml version="1.0" encoding="UTF-8"?>
<DocTree xmlns="http://wolfedgx.com/doc-list/1.0/">
    <DocDetails>
        <Title>Book Title</Title>
        <Author>Author Name</Author>
    </DocDetails>
    <ItemGroup id="10">
        <GroupCategory>52</GroupCategory>
        <Genre>Horror</Horror>
    </ItemGroup>
    <ItemGroup id="11">
        <GroupHierarchy>52</GroupHierarchy>
        <Delivery>2</Delivery>
        <GroupMember>95</GroupMember>
    </ItemGroup>
    <ItemGroup id="11">
        <GroupHierarchy>51</GroupHierarchy>
        <Delivery>55</Delivery>
        <GroupMember>100</GroupMember>
    </ItemGroup>
    <ItemGroup id="22">
        <GroupMemberNo>95</GroupMemberNo>
        <StoreName>Denver</StoreName>
        <StoreID>92</StoreID>
        <Staff>32</Staff>
    </ItemGroup>
    <ItemGroup id="52">
        <StoreREF>92</StoreREF>
        <StorePrice>1.99</StorePrice>
        <StoreLogistics>2.00</StoreLogisics>
        <ItemStored>5A</ItemStored>
        <LazyRef>Yes</LazyRef>
    </ItemGroup>
    <ItemGroup id="22">
         <GroupMemberNo>95</GroupMemberNo>
        <StoreName>Alaska</StoreName>
        <StoreID>22</StoreID>
        <Staff>2</Staff>
    </ItemGroup>
    <ItemGroup id="52">
        <StoreREF>22</StoreREF>
        <StorePrice>2.99</StorePrice>
        <StoreLogistics>4.00</StoreLogisics>
        <ItemStored>1A</ItemStored>
        <LazyRef>Mixed</LazyRef>
    </ItemGroup>
    <ItemGroup id="22">
         <GroupMember>100</GroupMember>
        <StoreName>Washington</StoreName>
        <StoreID>34</StoreID>
        <Staff>2</Staff>
    </ItemGroup>
    <ItemGroup id="52">
        <StoreREF>34</StoreREF>
        <StorePrice>2.99</StorePrice>
        <StoreLogistics>4.00</StoreLogisics>
        <ItemStored>1A</ItemStored>
        <LazyRef>Mixed</LazyRef>
    </ItemGroup>
    <ItemGroup id="90">
        <Misc>No additional information</Misc>
    </ItemGroup>
 </DocTree>

我想知道是否可以根据它们的 ItemGroup id 号验证这些元素。我不能使用 xsd 1.1,因为我必须使用 JAXB 来处理数据。另外,XML 是固定的,所以我无法对其进行重构。您会注意到数据实际上是相互关联的,验证这会很好,但这并不是绝对必要的,目前仅基于 ItemGroups 验证元素就很好了。

下面是对这个问题的补充,但不回答它。这是一个建议的 xsd 解决方法,但避免了基于 InfoGroup id 的验证,并且应该允许每个属性多次出现。

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://wolfedgx.com/doc-list/1.0/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="DocTree" type="ns:DocTree" xmlns:ns="http://wolfedgx.com/doc-list/1.0/"/>
<xs:complexType name="DocDetails">
    <xs:sequence>
        <xs:element type="xs:string" name="Title" maxOccurs="unbounded" minOccurs="0" />
        <xs:element type="xs:string" name="Author" maxOccurs="unbounded" minOccurs="0" />
   </xs:sequence>
  </xs:complexType>
    <xs:complexType>
        <xs:element name="InfoGroup">
            <xs:sequence>
                <xs:element type="xs:int" name="GroupCategory" maxOccurs="unbounded" minOccurs="0" />
                <xs:element type="xs:string" name="Genre" maxOccurs="unbounded" minOccurs="0" />
                <xs:element type="xs:int" name="GroupHierarchy" maxOccurs="unbounded" minOccurs="0" />
                <xs:element type="xs:int" name="Delivery" maxOccurs="unbounded" minOccurs="0" />
                <xs:element type="xs:int" name="GroupMember" maxOccurs="unbounded" minOccurs="0" />
                <xs:element type="xs:int" name="GroupMemberNo" maxOccurs="unbounded" minOccurs="0" />
                <xs:element type="xs:string" name="StoreName" maxOccurs="unbounded" minOccurs="0" />
                <xs:element type="xs:int" name="StoreID" maxOccurs="unbounded" minOccurs="0" />
                <xs:element type="xs:int" name="Staff" maxOccurs="unbounded" minOccurs="0" />
                <xs:element type="xs:int" name="StoreREF" maxOccurs="unbounded" minOccurs="0" />
                <xs:element type="xs:float" name="StorePrice" maxOccurs="unbounded" minOccurs="0" />
                <xs:element type="xs:float" name="StoreLogistics" maxOccurs="unbounded" minOccurs="0" />
                <xs:element type="xs:string" name="ItemStored" maxOccurs="unbounded" minOccurs="0" />
                <xs:element type="xs:string" name="LazyRef" maxOccurs="unbounded" minOccurs="0" />
                <xs:element type="xs:string" name="Misc" maxOccurs="unbounded" minOccurs="0" />
            </xs:sequence>
            <xs:attribute type="xs:int" name="id"/>
        </xs:element>
    </xs:complexType>
</xs:schema>

【问题讨论】:

    标签: xml validation xsd


    【解决方案1】:

    共现约束的经典示例。这需要 XSD 1.1。

    JAXB 实际上只适用于具有高度规则和稳定结构的 XML。在使用 JAXB 处理 XML 之前,请考虑使用 XSLT 将 XML 转换为其他内容。

    【讨论】:

    • 感谢@michael-kay,我也阅读了您的其他帖子,非常有帮助。我用建议的解决方法更新了这个问题,但它肯定偏离了验证(所以我觉得它不适合“答案”)。如果可能的话,我仍然会按照您的建议使用 xlst,然后验证。请让我知道您对建议的解决方法的看法。
    猜你喜欢
    • 2019-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多