我目前正在创建XML格式。我对于我想要这样做的地方有很多想法,但在开始时我想从小开始并允许可扩展性。我已经对XML属性与XML元素,何时使用它们,两者的优缺点等进行了大量阅读。普遍共识(见here和here)似乎尽可能使用XML元素,除非你绝对确定一段数据是原子的,永远不需要扩展,或者确实是关于如何处理元素的元数据。
所以这是我的问题。假设我遵循本指南并创建基本的XML文档,如此。
<person>
<name>John Doe</name>
</person>
我遵循了我认为最佳做法。这是目前最基本的形式,我将数据放在元素与属性中,以防我以后想要扩展它。现在让我说我已经使用这种格式一段时间了,我想扩展它。如何在不破坏任何希望在name元素的innertext中使用全名的现有进程的情况下这样做?
如果我像这样扩展它。
<person>
<name>John Doe
<firstname>John</firstname>
<lastname>Doe</lastname>
<alias>John Doe</alias>
</name>
</person>
它会破坏现有的过程,因为现在'name'的内容将是“John DoeJohnDoeJohn Doe”。我知道有办法解决这个问题,但重点是不要破坏希望innertext包含全名的现有内容。
我能想到的唯一可以轻松扩展的方法是创建'name'的新值属性。但如果我想要额外的复杂性怎么办?像多个'别名'值一样。使用属性是不可能的。
<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'的属性或带有innertext的子元素并不重要,因为最后我只需要使用一个新的元素名称。
在我看来,像这样的混合方法将是最灵活的并允许最大的可扩展性,但我无法找到某人这样做的例子。如果你从这开始......
<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>
在我看来,指南应尽可能使用元素,并将值放在标记内的某种“值”属性中。和往常一样,常识应该适用,你应该在适当时使用innertext,如消息,备忘录或备注字段。
我是否未能理解第一个示例中的一些关键设计元素,使其成为更好的方法?有没有人有过必须扩展XML模式同时保持反向兼容性并遇到相同问题或解决方案的经验?任何指导或专业提示将不胜感激。
答案 0 :(得分: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
解析器仍然完全有效。