【发布时间】:2016-11-18 21:39:38
【问题描述】:
我目前正在创建 XML 格式。我对我想要这个去哪里有很大的想法,但一开始我想从小处着手并考虑到可扩展性。我已经阅读了大量关于 XML 属性与 XML 元素的主题、何时使用它们、两者的优缺点等。普遍的共识(参见 here 和 here)似乎是使用 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