【问题标题】:XML best practices: planning for extensibilityXML 最佳实践:规划可扩展性
【发布时间】:2016-11-18 21:39:38
【问题描述】:

我目前正在创建 XML 格式。我对我想要这个去哪里有很大的想法,但一开始我想从小处着手并考虑到可扩展性。我已经阅读了大量关于 XML 属性与 XML 元素的主题、何时使用它们、两者的优缺点等。普遍的共识(参见 herehere)似乎是使用 XML在可能的情况下使用元素,除非您绝对确定一条数据是原子的并且永远不需要扩展,或者确实是关于如何处理元素的元数据。

所以这是我的问题。假设我遵循此指南并创建基本的 XML 文档,例如。

<person>
     <name>John Doe</name>
</person>

我遵循了我认为的最佳做法。这是目前工作的最基本的形式,我将数据放在元素和属性中,以防我以后想扩展它。现在假设我已经使用这种格式有一段时间了,我想扩展它。如何在不破坏任何现有进程的情况下做到这一点,这些进程期望名称元素的内部文本中有全名?

如果我像这样扩展它。

<person>
    <name>John Doe
        <firstname>John</firstname>
        <lastname>Doe</lastname>
        <alias>John Doe</alias>
    </name>
</person>

它会破坏现有的流程,因为现在“name”的内部文本将是“John DoeJohnDoeJohn Doe”。我知道有办法解决这个问题,但关键是不要破坏期望内部文本包含全名的现有内容。

我能想到的轻松扩展它的唯一方法是创建“名称”的新值属性。但是,如果我想要额外的复杂性怎么办。就像多个“别名”值一样。使用属性是不可能的。

<person>
     <name firstname="John" lastname="Doe" alias="John Doe">John Doe</name>
</person>

似乎在不破坏现有流程的情况下真正扩展它的唯一方法是选择一个新的元素名称。

<person>
    <name>John Doe</name>
    <extendedname>
        <firstname>John</firstname>
        <lastname>Doe</lastname>
        <alias>John Doe</alias>
        <alias>Jon Doe</alias>
    </extendedname>
</person>

所以这可以解决我的问题,但我问自己“为什么'name'作为一个元素而不是一个属性很重要?”在我看来,最终“name”是“person”的属性还是带有内部文本的子元素并不重要,因为最后我只需要使用新的元素名称。

我突然想到,像这样的混合方法将是最灵活的,并且可以实现最大的可扩展性,但我真的找不到有人这样做的例子。如果你从这个开始......

<person>
     <name value="John Doe" />>
</person>

它可以很容易地变成这样,而不会破坏任何现有流程,并且仍然允许进一步扩展。

<person>
    <name value="John Doe" />
        <firstname value="John" />
        <lastname value="Doe" />
        <alias value="John Doe" />
        <alias value="Jon Doe" />
    </name>
</person>

在我看来,指导应该是尽可能使用元素,并将值放在标签内的某种“值”属性中。与往常一样,应遵循常识,并且应在适当的时候使用内部文本,例如消息、备忘录或备注字段。

我是否未能理解第一个示例中的一些关键设计元素,这使得它成为一种更好的方法?有没有人有过在保持反向兼容性的同时扩展 XML 模式并在这里遇到相同问题或解决方案的经验?任何指导或专业提示将不胜感激。

【问题讨论】:

  • 命名空间,命名空间,命名空间,命名空间。
  • 也就是说:为您的第 1 版内容提供命名空间。如果您进行了不兼容的更改,请使用新的命名空间。然后,您可以在一个文档中包含来自两个命名空间的内容,如果您想生成与两个版本兼容的内容,和/或定义和记录您自己的应用程序逻辑,以了解如何处理混合文档。
  • 是的,命名空间,我用过它们,但是你必须生成 2 个文档对吗?旧命名空间中的 1 个文档,新命名空间中的 1 个文档。那时你还没有真正扩展任何东西,你只是创建了一种新格式。
  • “必须生成两个文档”?仅当您未将 v2 解析器定义为仍支持 v1 元素时。
  • ...如果您不能拥有混合命名空间的文档,那就更不重要了。

标签: xml xml-attribute innertext


【解决方案1】:

假设您构建解析器以识别先前版本的容器元素,您可以这样做:

<doc xmlns:v1="http://example.com/yourformat/1.0"
     xmlns:v2="http://example.com/yourformat/2.0">
  <v1:person>
    <v1:name>John Doe</v1:name>
    <v2:name>
      <v2:firstname>John</v2:firstname>
      <v2:lastname>Doe</v2:lastname>
      <v2:alias>John Doe</v2:alias>
      <v2:alias>Jon Doe</v2:alias>
    </v2:name>
  </v1:person>
</doc>

显然,如果您不喜欢所有前缀,请将v2 设为默认xmlns


这样,即使添加了v2 内容,您的文档对于v1 解析器仍然完全有效。

【讨论】:

  • 是的,虽然可能需要更多背景知识,但这会起作用。我将从服务器收集数据,然后将其写入 XML 文件,然后将其提取、存储并提取到数据库中以进行额外报告。涉及的团队和个人很多,他们的技能水平各不相同。我可以处理名称空间,但更改是好的,有人只是要获取数据,执行 $Report = [xml]Get-Content report.xml,然后解析它,而不考虑名称空间。因此,我希望保留 1 个名称空间并计划使其可扩展。
  • 冒着轻率的风险:如果您想要一种简单、愚蠢的格式,任何人都可以使用而无需过多关注他们在做什么,我可以指导您使用 JSON 吗?
  • 所以我承认这一点。 XML 命名空间是执行此操作的正确方法,但我的问题实际上是关于应尽可能使用元素的一般指导,因为它们更具可扩展性。如果您不能在不创建新命名空间的情况下使用内部文本扩展元素,这与使用属性然后决定它应该是需要新命名空间的复杂元素实际上没有什么不同。无论如何,我非常感谢您的洞察力。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-05
  • 1970-01-01
  • 1970-01-01
  • 2011-04-08
  • 1970-01-01
相关资源
最近更新 更多