3

我正在为一个一直使用这种 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>

你怎么看?

如果它们都可以,是否有“最佳实践”?

4

8 回答 8

6

只要所有元素都包含在单个根元素中,它实际上没有任何问题。

任何一种关闭标签都是可以接受的,尽管我建议所有没有其他标签的元素使用自关闭标签。

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

于 2009-11-20T15:10:33.273 回答
3

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

我会就我的观点说几句。

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

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

我想更清楚一点,但我的英语不太熟练,无法更好地解释我对这个主题的想法。

于 2009-11-20T15:25:23.773 回答
3

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

只要 XML 有一个名称空间,它就没有问题。

于 2009-11-20T15:10:42.503 回答
2

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

一、局限性:

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

显着优势:

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

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

(这可能会导致大问题。在 WPF 中,您可以使用 XAML 中的属性来存储对象属性的值,这些属性在设置时会产生副作用。这样做会导致非常难以诊断的错误 - 只是因为您设置Binding了您在设置之前的 XAMLSelectedItem并不意味着XamlReader当它构造您的 XAML 表示的对象时会这样做,并且如果它尝试SelectedItem在一个还没有 a 的对象上设置Binding它会引发异常。你可以整天查看您的 XAML,却看不到为什么会发生这种情况。)

在代码中,使用属性的好处是不言而喻的。要使用DOM(在 C# 中)设置和获取foo元素上的属性值:XmlDocument

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,或完全避免 DOM 并使用序列化),但使用元素本质上更复杂。

在您的示例中,使用属性可能没问题;看起来它们代表了一个简单的名称/值对映射,顺序无关紧要。标题可能是个例外。如果允许它们包含标记是可取的,你会伤心的。

编辑:

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

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

<ListBox Binding="{...}" SelectedItem="..." ... />

做这个:

<ListBox>
   <ListBox.Binding>...</ListBox.Binding>
   <ListBox.SelectedItem>...</ListBox.SelectedItem>
   ...
于 2009-11-20T19:14:49.843 回答
1

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

我将属性用于简短的项目,这些项目非常特定于它们所附加的元素,并且没有机会扩展到多个值。我倾向于制作布尔值、数值和枚举值属性。例如,对于图像参考元素,我会设置宽度、高度和格式属性。

我将元素用于更长的值(特别是那些可以想象为任何长度的元素),尤其是那些以后可能扩展到更复杂结构的元素。例如,对于图像引用元素,我会将标题、标题、描述、URL 和其他可能冗长的自由文本值作为图像引用元素的子元素。

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

于 2009-11-20T16:19:50.543 回答
1

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

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

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

于 2009-11-20T15:13:48.737 回答
1

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

来自w3schools

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

...

使用属性的一些问题是:

* 属性不能包含多个值(元素可以)
* 属性不能包含树结构(元素可以)
* 属性不容易扩展(以备将来更改)

属性难以阅读和维护. 使用数据元素。对与数据不相关的信息使用属性。

使用元素。

于 2009-11-20T15:41:32.633 回答
1

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

于 2009-11-20T15:15:31.387 回答