2016-07-15 81 views
0

我目前正在创建XML格式。我对我想要去的地方有很大的想法,但是一开始我想从小开始并考虑到可扩展性。我在XML属性和XML元素的主题上做了大量的阅读,何时使用它们,两者的优点/缺点等。一般的共识(参见herehere)似乎是在可能的情况下使用XML元素你绝对相信一块数据是原子的,永远不需要扩展,或者真正的元数据是关于如何处理元素的。XML最佳实践:规划可扩展性

所以这是我的问题。说我遵循这个指导,并创建这样的基本XML文档。

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

我遵循了我认为最好的做法。这是现在最基本的工作形式,我将数据放在元素和属性中,以备日后扩展。现在让我们说我一直在使用这种格式,我想扩展它。我怎样才能做到这一点,而不会打破任何现有的名称元素的内联字母全名的过程?

如果我这样扩展它。

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

这将打破现有的流程,因为现在的“名”的innerText属性将是“约翰·多伊DoeJohnDoeJohn”。我知道有办法解决这个问题,但重要的是不要打破现有的期望无限文本包含全名的事情。

我能想到的简单扩展这个的唯一方法是创建'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'是'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

命名空间,命名空间,命名空间,命名空间。 –

+0

也就是说:为您的版本-1内容提供一个命名空间。如果您做出不兼容的更改,请使用新的名称空间。然后,如果您想要生成与两个版本兼容的内容,并且/或者定义和记录您自己的应用程序逻辑以处理混合文档的方式,则可以在单个文档中包含来自两个名称空间的内容。 –

+0

是的,命名空间,我用过它们,但是你必须生成2个文档吗? 1个文档位于旧命名空间中,1个位于新命名空间中。在那个时候,你还没有真正扩展你的任何东西,你只是创建了一个新的格式。 – Lavaftw

回答

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解析器。

+0

是的,这可能会工作,但也许需要更多的背景。我将从服务器收集数据,然后将其写入一个XML文件,然后将其取出,存储并存入数据库以进行其他报告。有很多团队和个人参与其中,具有不同的技能水平。我可以处理名称空间,但更改是好的,只需要获取数据,执行$ Report = [xml] Get-Content report.xml并解析它,而不考虑名称空间。因此,我希望保留1个名称空间,并且只是为了扩展它的计划。 – Lavaftw

+0

面临浮躁的风险:如果您想要一个任何人都可以使用的简单,笨拙的格式,而不必关注他们正在做的事情,我可以指导您使用JSON吗? –

+0

所以我承认这一点。 XML命名空间是这样做的正确方式,但我的问题实际上是关于应尽可能使用元素的一般指导,因为它们更具可扩展性。如果你不能用一个内部文本扩展一个元素而不创建一个新的名称空间,那么它与如果你使用一个属性并且决定它应该是一个需要一个新的名称空间的复杂元素没有区别。无论如何,我很感激你的洞察力。 – Lavaftw