使用父XML元素作为重复出现的子元素的容器?

bpo*_*ter 9 xml xsd coding-style

假设您希望允许某些特定的XML元素出现0次以上.例如,<record>元素可以多次出现:

<repository>
  <record>Record 1</record>
  <record>Record 2</record>
  <record>Record 3</record>
</repository>
Run Code Online (Sandbox Code Playgroud)

是否有任何令人信服的理由将父元素作为容器包含在内?例如,以下使用<recordSet>元素来包含<record>元素:

<repository>
  <recordSet>
    <record>Record 1</record>
    <record>Record 2</record>
    <record>Record 3</record>
  </recordSet>
</repository>
Run Code Online (Sandbox Code Playgroud)

在提出这个问题之前,我试图找到任何相关的问题,所以如果已经提出问题我会道歉.提前感谢任何和所有输入!


编辑 - 2009年7月22日:

感谢大家的出色反馈!(我会评论/投票给人,但我还没有足够的声望点.)我可能会继续这条路线,我也想感谢@ 16bytes的建议,包括简单命名父母通过使用复数的重复子元素.

Chr*_*ott 10

您偶然发现了我的第二个XML设计指南规则(第一个是仅使用ID和真实元数据的属性,第三个是不使用命名空间,除非您知道自己在做什么)我尝试使用时设计xml文档.除了是一个很好的经验法则,它还使您的文档:

  • 更容易在XML Schema或其他验证语言中建模
    • 也更容易重复使用复杂类型
  • 更容易阅读(恕我直言)
  • 用户在遍历文档时更容易理解
  • (上述)更容易绑定到您选择的OOP对象

一个建议,我会尝试:

<Root>
   <Items>
     <Item>a</Item>
     <Item>b</Item>
     <Item>c</Item>
   </Items>
</Root>
Run Code Online (Sandbox Code Playgroud)

更简单的"s"后缀更简洁,更易于记忆和应用.如果你使用泛型集合名词,你或同事最终会忘记哪一个,所以你会看到与混合了Container的列表混合的集合.但这不仅仅是一种风格而不是良好的实践,我不想发动宗教战争;)

(元素的UpperCamel!属性的lowerCamel! - )


Ric*_*ler 4

拥有父元素可以更轻松地识别 XML 的各个部分,并使处理程序更轻松地将子元素映射到集合。如果您有一个禁止使用属性的系统(有些确实如此,这很烦人),您还需要使用包装元素来区分属于特定子项的属性(例如 ids)。

除此之外,省略父元素是有效的,并且可以使文件明显不那么冗长。

在您的第一个示例中,用户元素可能与记录混合在一起,这是有效的,但可能很难发现:

<repository>
  <record>Record 1</record>
  <record>Record 2</record>
  <user>Bill</user>
  <record>Record 3</record>
</repository>
Run Code Online (Sandbox Code Playgroud)

而使用周围元素,您可以分隔集合,并拥有该集合的多个实例:

<repositories>
  <users>
    <user>Bill</user>
  </users>
  <repository>
    <id>id1</id>
    <recordSet>
      <id>recordSet1</id>
      <record>Record 1</record>
      <record>Record 2</record>
      <record>Record 3</record>
    </recordSet>
    <recordSet>
      <id>recordSet2</id>
      <record>Record 1</record>
      <record>Record 2</record>
      <record>Record 3</record>
    </recordSet>
  </repository>
  <repository>
    <id>id2</id>
    <recordSet>
      <record>Record 1</record>
      <record>Record 2</record>
      <record>Record 3</record>
    </recordSet>
  </repository>
</repositories>
Run Code Online (Sandbox Code Playgroud)