这是一个很好的XML吗?

时间:2009-11-20 15:07:18

标签: xml normalization

我正在为一个使用此XML结构的客户工作,以获取他的网站内容:

<section title="title1" layoutType="VideoViewer" xmlPath="xml/ita/title1.xml" pageTitle="extended title" previewImg=""/>

<section title="another title" layoutType="TimeLine" xmlPath="xml/ita/timeline.xml" textFile="" pageTitle="extended title for timeline"></section>

我对XML很陌生,但这对我来说并不好看。除了关闭标记的不同方式(使用/>自动关闭或使用</section>显式关闭)我会认为XML应该更像

<section> 
  <title>title1</title> 
  <layoutType>"VideoViewer" </layoutType>
  <xmlPath>xml/ita/title1.xml </xmlPath> 
  <pageTitle>extended title</pageTitle> 
  <previewImg/>
</section>

<section>
 ...etc etc..
</section>

您怎么看?

如果他们都没问题,是否有“最佳实践”?

8 个答案:

答案 0 :(得分:6)

只要所有元素都包含在一个根元素中,就没有任何实际的错误。

任何一种结束标记都是可以接受的,虽然我建议在其中没有其他标记的所有元素中使用自闭标记。

至于结构(标签与属性),这是一个意见问题,根据定义,两种选择都不是更好。

答案 1 :(得分:3)

为什么你认为XML应该更像那样?第一个是以属性为中心的;你提出的是以元素为中心的。虽然现在以元素为中心已经变得越来越普遍,但以属性为中心的方法肯定没有错,它可以使一些事情变得更加清晰。

只要XML有一个命名空间,那就没有错。

答案 2 :(得分:3)

两者都是正确的。这只是个人品味的问题。

我会在我的观点上花一些话。

当我学习XML时,我已经了解到当你必须存储一个简单的属性时,属性比子元素更可取。 简单来说,我的意思是非结构化属性。

非结构化部分很简单:属性可以表示为字符串。 对于单身,我的意思是你不能为一个属性分配超过一个值 但您可以重复相同的子元素以在父节点内创建集合/集合。

我想更清楚但是我不太精通英语来更好地解释我对这个问题的想法。

答案 3 :(得分:2)

我认为在该示例XML中使用属性没有任何问题。属性有许多元素没有的限制,以及一些重要的优点。

首先,限制:

  • 属性可能只包含简单内容。
  • 属性名称在元素中必须是唯一的。
  • 根据定义,XML中的属性排序并不重要;您不能依赖DOM以任何特定顺序迭代或保存属性。
  • 属性不是节点,这意味着在XPath中访问它们的方式存在一些怪癖(例如,XSLT标识转换中使用的模式node() | @*)和DOM中(例如在.NET中, XmlAttribute XmlNode派生自XmlAttributeCollection,即使属性不是节点,XmlNodeList 派生自XmlNode,即使它是Binding的列表{1}}对象 - 这有很好的理由,但是如果你是新手的话会很混乱。)

显着优势:

  • 因为属性名称在元素中必须是唯一的,并且只能包含简单内容,所以设置和获取属性值的DOM方法比使用DOM方法设置和获取元素中的值要简单得多。
  • 由于属性排序不重要,因此不需要创建和使用属性的代码来关注它们的排序。
  • 因为属性可能只包含简单内容,所以为它们编写模式定义会更容易。
  • 属性的标记比元素的标记更简洁。

属性非常干净地同构化到地图/字典上。您可以使用属性作为由名称/值对组成的任何数据结构的可持久形式,只要可以将名称限制为有效的XML名称和将值限制为文本 - 并且只要您构造数据结构时它就不会不管你填充它的顺序是什么。

(这可能会导致很大的问题。在WPF中,您可以使用XAML中的属性来存储在设置时具有副作用的对象属性的值。这样做会导致非常难以诊断的错误 - 只是因为在设置SelectedItem之前在XAML中设置XamlReader并不意味着SelectedItem在构造XAML所代表的对象时会发生这种情况,并且如果它试图设置Binding对象没有foo,但它会抛出异常。你可以整天看看你的XAML而不知道为什么会发生这种情况。)

在代码中,使用属性的好处是不言而喻的。使用XmlDocument DOM(在C#中)设置和获取元素的elm.SetAttribute("foo", value); value = elm.GetAttribute("foo"); 属性的值:

foo

在元素上设置并获取XmlElement fooElm = (XmlElement)elm.SelectSingleNode("foo"); if (fooElm == null) { elm.OwnerDocument.CreateElement("foo"); elm.AppendChild(fooElm); } fooElm.InnerText = value; XmlElement fooElm = (XmlElement)elm.SelectSingleNode("foo"); value = fooElm != null ?? fooElm.InnerText : ""; 元素的值:

XDocument

当然有更有效的方法来执行上述操作(编写辅助方法,使用XmlDocument而不是XamlReader,或完全避免使用DOM并使用序列化),但使用它本身就更复杂元件。

在您的示例中,使用属性可能没问题;它看起来像是一个简单的名称/值对映射,具有无关紧要的排序。例外情况可能是标题;如果允许它们包含标记,那么你会感到悲伤。

修改

实际上,我相信Binding会按照它们在XAML中出现的顺序处理属性,因此如果您在XAML中SelectedItem之前设置XamlReader,它可能不会导致异常 - 只要<ListBox Binding="{...}" SelectedItem="..." ... /> 正在读取XAML的实际文本。风险实际上是读取和写入XML文档的工具将改变XAML文档中属性的顺序。 KaXaml是否保留了它编辑的XAML文档中的属性顺序?它不应该拥有

无论如何,XAML中的解决方案很简单:而不是这样做:

<ListBox>
   <ListBox.Binding>...</ListBox.Binding>
   <ListBox.SelectedItem>...</ListBox.SelectedItem>
   ...

这样做:

{{1}}

答案 4 :(得分:1)

在我看来,你的方法更好。 xml属性(如title =“blah”)用于定义特定标记的属性,但是当您进入更复杂的数据结构时,您希望根据对象进行更多思考,其中标记的属性实际上只是定义了额外的数据(如数据类型,格式等)。

您的样本朝着正确的方向发展,但这完全取决于您如何选择数据建模。

例如“类型”之类的东西可能是该部分的适当属性(如果不确切知道你的建模,很难知道)但我会假设某些东西是合适的

答案 5 :(得分:1)

当你公开承认自己不熟悉XML时,我会指出你W3 Schools的方向。至于你的问题,确实没有正确或错误的答案都是合理的。这取决于您自己的特殊偏好。

答案 6 :(得分:1)

自动关闭标签很棒,但我认为使用所有属性都不会被视为“最佳做法”。属性比元素有更多限制。

来自w3schools

  

没有关于何时使用属性以及何时使用元素的规则。属性在HTML中很方便。在XML中,我的建议是避免它们。请改用元素。

  ...

  使用属性的一些问题是:

      *属性不能包含多个值(元素可以)
      *属性不能包含树结构(元素可以)
      *属性不易扩展(以备将来更改)
  
属性难以阅读和维护。使用元素数据。使用属性来获取与数据无关的信息。

使用元素。

答案 7 :(得分:1)

我个人设计XML方言的风格涉及属性和元素的混合,对元素很重要。我的一般经验法则是,每行不得超过80个字符(不包括前导空格),因此不应要求换行以便舒适地读取。

我将属性用于非常特定于它们所附加元素的简短项目,并且不可能被扩展为多个值。我倾向于制作布尔值,数值和枚举值属性。例如,对于图像参考元素,我将创建宽度,高度和格式属性。

我使用元素来获得更长的值(特别是那些可以是任意长度的元素),特别是那些可以延伸到更复杂结构的元素。例如,对于图像引用元素,我将为图像引用元素创建标题,标题,描述,URL和其他可能冗长的自由文本值子元素。

XML应该易于人类阅读。 XML方言应该是健壮的,并且在修改时不会破坏系统。如有疑问,请使用元素。