我看到使用该示例XML中的属性没有任何问题。属性具有许多元素所没有的限制,以及一些显着的优点。
首先,限制:
- 属性可能只包含简单内容。
- 属性名称在元素中必须是唯一的。根据定义,属性的排序在XML中并不重要;您不能依靠DOM来按照任何特定顺序遍历或保存属性。
- 属性不是节点,这意味着您在XPath中访问它们时存在一些偏心(例如,在XSLT标识转换中使用的模式
node() | @*
)以及在DOM中(例如,NET,XmlAttribute
派生自XmlNode
即使属性不是节点,并且XmlAttributeCollection
不是派生自XmlNodeList
即使它是一个XmlNode
对象的列表 - 这是有很好的理由,但它是相当混乱,如果你是新来的它)。
的显著优点:
- 由于属性名必须是一个元素中是唯一的,并且只能包含简单内容,对DOM方法来设置和获取属性值是显著简单比DOM使用在元素中设置和获取值的方法。
- 由于属性排序并不重要,因此不需要创建和使用属性来关注排序的代码。
- 由于属性只能包含简单内容,因此为它们编写模式定义会更容易。
- 属性的标记比元素的标记更简洁。
属性同构到地图/字典非常干净。您可以使用属性作为任何由名称/值对组成的数据结构的可持久化形式,只要可以将名称限制为有效的XML名称并将值限制为文本 - 并且只要构建它所执行的数据结构无论你填充什么样的顺序。
(这可能会导致很大的问题。在WPF中,你可以使用XAML中的属性来存储对象属性的值,它们在设置时会产生副作用。对于难以诊断的错误 - 仅仅因为您在设置SelectedItem
之前在您的XAML中设置了Binding
并不意味着XamlReader
将在构建XAML所代表的对象时尝试设置SelectedItem
在一个没有Binding
的物体上,它会抛出一个e xception。你可以整天看看你的XAML,看不出为什么会发生这种情况。)
在代码中,使用属性的好处是不言而喻的。来设置和使用XmlDocument
DOM(在C#)得到的元件上的foo
属性的值:
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的顺序属性,因此,如果你在你的XAML SelectedItem
之前设置Binding
它可能不会导致异常 - 所以只要XamlReader
正在从XAML的实际文本中读取。实际上,读取和写入XML文档的工具会改变XAML文档中属性的排序。 KaXaml是否保留了它所编辑的XAML文档中属性的顺序?它不应该有到。
无论如何,在XAML解决方法很简单:不是这样:
<ListBox Binding="{...}" SelectedItem="..." ... />
做到这一点:
<ListBox>
<ListBox.Binding>...</ListBox.Binding>
<ListBox.SelectedItem>...</ListBox.SelectedItem>
...
顺便说一句,这是很好的询问最佳实践,但我不会”建议改变一个没有损坏的工作系统,除非你需要增加你的计费时间:-) – NVRAM 2009-11-20 16:22:23