【问题标题】:Each element of a collection must go between their corresponding <element></element> in XSD?集合的每个元素都必须在 XSD 中对应的 <element></element> 之间?
【发布时间】:2016-10-05 12:59:22
【问题描述】:

我收到了第一个版本的 WSDL,其中包含以下类型的模式:

<xs:complexType name="AComplexType">
   <xs:sequence>
     <xs:element minOccurs="0" name="description" nillable="true" type="xs:string"/>
     <xs:element minOccurs="0" name="version" nillable="true" type="xs:int"/>
   </xs:sequence>
</xs:complexType>

<xs:complexType name="Response">
  <xs:sequence>
    <xs:element minOccurs="0" name="responseDescription" nillable="true" type="xs:int"/>
    <xs:element maxOccurs="unbounded" minOccurs="0" name="listOfElements" nillable="true" type="AComplexType"/>
  </xs:sequence>
</xs:complexType> 

以下xml对上面的xsd有效:

<Response>
  <responseDescription>A response description</responseDescription>
  <listOfElements>
    <description>An element descrition</description>
    <version>1</version>
    <description>Another element descrition</description>
    <version>1</version>
    ...
  </listOfElements>
</Response>

另外,我可以使用 xjc 为这种类型创建类,所以这似乎是一个有效的模式。

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Response", propOrder = {
    "responseDescription",
    "listOfElements"
})
public class ConsultaExpedienteGATResponse {


    @XmlElementRef(name = "estado", namespace = "...", type = JAXBElement.class, required = false)
    protected JAXBElement<String> responseDescription;
    @XmlElement(nillable = true)
    protected List<AComplexType> listOfElements;

    ...
}

但是,我认为这种模式是无效的,应该是这样的:

<xs:complexType name="Response">
  <xs:sequence>
    <xs:element minOccurs="0" name="responseDescription" nillable="true" type="xs:int"/>
      <xs:element name="listOfElements">
        <xs:complexType>
         <xs:sequence>
          <xs:element maxOccurs="unbounded" name="oneElement" type="AComplexType"/>
         </xs:sequence>
        </xs:complexType>
       </xs:element>
  </xs:sequence>
</xs:complexType> 

使用此架构,xml 略有不同:

<Response>
  <responseDescription>A response description</responseDescription>
  <listOfElements>
    <oneElement>
      <description>An element descrition</description>
      <version>1</version>        
    </oneElement>
    <oneElement>
      <description>Another element descrition</description>
      <version>1</version>        
    </oneElement>
    ...
  </listOfElements>
</Response>

所以,我想知道每个选项是否有优缺点(例如解析 xml 的性能更好),或者两者中的一个是采用还是默认选择。

【问题讨论】:

    标签: xml xsd jaxb xsd-validation


    【解决方案1】:

    两种编写模式的风格有时被称为“百叶窗”和“俄罗斯娃娃”。谷歌这些术语,你会发现很多人争论在什么情况下哪个是最好的。就像所有编码风格的问题一样,讨论往往会产生比光更多的热量。两者都是完全有效的,而且都不会带来任何性能优势。

    我自己的偏好倾向于“百叶窗”(具有命名的全局元素声明和/或命名的复杂类型,但通常不会两者兼而有之);因为全局声明是可重用的。如果您正在使用模式感知 XSLT 和 XQuery,这将特别有用,因为全局元素和类型名称随后可以在您的 XSLT/XQuery 代码中被利用。

    【讨论】:

    • 这是真的,但 OP 询问的是实际的 XML 设计,而不是 XSD 设计模式。
    【解决方案2】:

    此决定不会影响性能。

    您以前的设计依赖于邻接来将描述与版本相关联。这不是“无效的”。虽然您会在基于文档的 XML 中看到这种模式(例如段落前面的标题),但它对于面向数据的 XML 来说并不理想。

    而是通过层次结构使关联更加明确,就像您在后一个设计中所做的那样,或者通过属性(尤其是version,它可能不需要从属标记)。另见XML attribute vs XML element

    【讨论】:

    • 是的,它依赖于邻接,这就是为什么我认为它无效,因为它看起来非常“脆弱”。此外,当我谈论性能时,我在想解析器如何知道一个元素结束而另一个元素开始(似乎更多的工作依赖于开始和结束标签)。另一方面,由于标签更少,我们可以认为第一个选项更高效。
    • 我同意你的观点,第一个选项更适合面向数据的 XML,但我没有充分的理由拒绝其他团队提出的模式。
    • 第一个选项依赖于邻接,更适合面向 document 的 XML。 (您的评论倒转了,可能是错字。)选择第二个选项,这对于面向数据的 XML 更好,这就是您所拥有的,并且如果您需要这样做,它将更好地映射到对象。同样,性能根本不是这里的问题。您永远不会达到标记开销成为系统瓶颈的地步。
    • 是的,是一个错字。我的意思是“我同意你的观点,last 选项更适合面向数据的 XML”。谢谢kjhughes
    • 不客气。如果有帮助,请accept这个答案。谢谢。
    【解决方案3】:

    虽然是xml

    <Response>
      <responseDescription>A response description</responseDescription>
      <listOfElements>
        <description>An element descrition</description>
        <version>1</version>
        <description>Another element descrition</description>
        <version>2</version>
        ...
      </listOfElements>
    </Response>
    

    对指定的第一个模式有效,当它被解组到由 xjc 生成的类(带有 JAXB 注释)中时,属性 listOfElements 是一个仅包含最后一个元素的列表(在这种情况下带有描述“另一个元素描述”和版本 2) 的元素。

    这个模式的有效xml真的是

    <Response>
      <responseDescription>A response description</responseDescription>
      <listOfElements>
        <description>An element descrition</description>
        <version>1</version>
      </listOfElements>
      <listOfElements>
        <description>Another element descrition</description>
        <version>2</version>
      </listOfElements>
    </Response>
    

    (混淆来自于使用 WSDL 的开发人员手动生成的不正确的 xml,但随后我通过 SOAP UI 为该 WSDL 创建了一个请求,并且错误变得清晰)。

    剩下的就是定义是否最好为列表设置一个根元素,例如

    <Response>
      <responseDescription>A response description</responseDescription>
      <listOfElements>
        <AComplexType>
          <description>An element descrition</description>
          <version>1</version>
        </AComplexType>
        <AComplexType>
          <description>Another element descrition</description>
          <version>2</version>
        </AComplexType>
      </listOfElements>
    </Response>
    

    但要回答我最初的问题,描述的第一个 XML 是错误的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多