.NET XAML 服务的 XAML 命名空间

XAML 命名空间是在 XML 命名空间的定义上扩展的一个概念。 与 XML 命名空间类似,你可以使用标记中的 xmlns 属性定义 XAML 命名空间。 XAML 命名空间也可以用 XAML 节点流和其他 XAML 服务 API 表示。 本主题定义 XAML 命名空间概念,并描述如何定义 XAML 命名空间,以及 XAML 架构上下文和 .NET XAML 服务的其他方面如何使用 XAML 命名空间。

XML 命名空间和 XAML 命名空间

XAML 命名空间是一个专用 XML 命名空间,就像 XAML 是 XML 的专用形式并对其标记使用基本 XML 形式一样。 在标记中,可通过应用于元素的 xmlns 属性声明 XAML 命名空间及其映射。 可以对声明 XAML 命名空间的同一元素进行 xmlns 声明。 对元素进行的 XAML 命名空间声明对该元素、该元素的所有属性以及该元素的所有子元素均有效。 属性可以使用与包含该属性的元素不同的 XAML 命名空间,前提是属性名称本身在标记中引用前缀作为其属性名称的一部分。

XAML 命名空间与 XML 命名空间的区别在于,XML 命名空间可用于引用架构或仅用于区分实体。 对于 XAML,XAML 中使用的类型和成员最终必须解析为后备类型,并且 XML 架构概念不适用于此功能。 XAML 命名空间包含 XAML 架构上下文必须提供才能执行此类型映射的信息。

XAML 命名空间组件

XAML 命名空间定义有两个组件:前缀和标识符。 当 XAML 命名空间在标记中声明或在 XAML 类型系统中定义时,这两个组件都存在。

前缀可以是 XML 1.0 规范中的 W3C 命名空间所允许的任何字符串。 根据约定,前缀通常是短字符串,因为前缀在典型的标记文件中会重复多次。 某些旨在用于多个 XAML 实现的 XAML 命名空间使用特定的常规前缀。 例如,XAML 语言 XAML 命名空间通常使用前缀 x 进行映射。 你可以定义默认 XAML 命名空间,其中前缀未在定义中给出,但如果由 .NET XAML 服务 API 定义或查询,则表示为空字符串。 通常,系统会故意选择默认 XAML 命名空间,以便通过 XAML 实现技术及其方案和词汇来提升前缀省略标记的最大数量。

标识符可以是 XML 1.0 规范中的 W3C 命名空间所允许的任何字符串。 根据约定,XML 命名空间或 XAML 命名空间的标识符通常以 URI 形式提供,通常用作协议限定的绝对 URI。 通常,定义特定 XAML 词汇的版本信息隐含在路径字符串中。 XAML 命名空间在 XML URI 约定之外增加了一个额外的标识符约定。 对于 XAML 命名空间,标识符用于传达 XAML 架构上下文所需的信息,以便解析在该 XAML 命名空间下指定为元素的类型,或将属性解析为成员。

为了将信息传达给 XAML 架构上下文,XAML 命名空间的标识符可能仍采用 URI 形式。 但是,在这种情况下,URI 同时被声明为特定程序集或程序集列表中的匹配标识符。 这是在程序集中通过使用 XmlnsDefinitionAttribute 对程序集进行属性设置来完成的。 .NET XAML 服务中的默认 XAML 架构上下文支持这种方法,即标识 XAML 命名空间并支持属性化程序集中基于 CLR 的类型解析行为。 一般来讲,此约定可用于 XAML 架构上下文包含 CLR 或基于默认 XAML 架构上下文的情况,这是从 CLR 程序集读取 CLR 属性所必需的。

XAML 命名空间也可以通过用于传达 CLR 命名空间和类型定义程序集的约定来标识。 此约定用于包含类型的程序集中不存在 XmlnsDefinitionAttribute 属性的情况。 此约定可能比 URI 约定更复杂,并且还可能产生歧义和重复,因为有多种方法可以引用程序集。

使用 CLR 命名空间和程序集约定的标识符的最基本形式如下所示:

clr-namespace:clrnsName; assembly=assemblyShortName

clr-namespace:; assembly= 是语法的文字部分。

clrnsName 是标识 CLR 命名空间的字符串名称。 此字符串名称包括任何内部点字符 (.),这些字符提供有关 CLR 命名空间及其与其他 CLR 命名空间之间关系的提示。

assemblyShortName 是程序集的字符串名称,用于定义可用于 XAML 的类型。 通过声明的 XAML 命名空间访问的类型应由程序集定义,并在 clrnsName 指定的 CLR 命名空间内声明。 此字符串名称通常与 AssemblyName.Name 报告的信息相类似。

CLR 命名空间和程序集约定的更完整定义如下所示:

clr-namespace:clrnsName; assembly=assemblyName

assemblyName 表示任何作为 Assembly.Load(String) 输入合法的字符串。 此字符串可以包含区域性、公钥或版本信息(这些概念的定义在 Assembly 的参考主题中定义)。 COFF 格式和证据(由 Load 的其他重载使用)与 XAML 程序集加载目的无关;所有加载信息都必须显示为字符串。

若要确保 XAML 安全性,或消除通过简单名称加载程序集时可能存在的歧义或预先存在于缓存或应用程序域中的歧义,为程序集指定公钥是一种有用的方法。 有关详细信息,请参阅 XAML 安全注意事项

XAML 服务 API 中的 XAML 命名空间声明

在 XAML 服务 API 中,XAML 命名空间声明由 NamespaceDeclaration 对象表示。 如果要在代码中声明 XAML 命名空间,请调用 NamespaceDeclaration(String, String) 构造函数。 nsprefix 参数指定为字符串,为这些参数提供的输入对应于本主题前面提供的 XAML 命名空间标识符和 XAML 命名空间前缀的定义。

如果将 XAML 命名空间信息作为 XAML 节点流的一部分或通过对 XAML 类型系统的其他访问来进行检查,则 NamespaceDeclaration.Namespace 会报告 XAML 命名空间标识符,NamespaceDeclaration.Prefix 会报告 XAML 命名空间前缀。

在 XAML 节点流中,XAML 命名空间信息可以显示为 XAML 节点,位于其应用到的实体之前。 这包括 XAML 命名空间信息位于 XAML 根元素的 StartObject 之前的情况。 有关更多信息,请参见 Understanding XAML Node Stream Structures and Concepts

对于许多使用 .NET XAML 服务 API 的方案,至少应存在一个 XAML 命名空间声明,并且该声明必须包含或引用 XAML 架构上下文所需的信息。 XAML 命名空间必须指定要加载的程序集,或者帮助解析命名空间和程序集中已由 XAML 架构上下文加载或其已知的特定类型。

若要生成 XAML 节点流,XAML 类型信息必须通过 XAML 架构上下文提供。 如果不先确定要创建的每个节点的相关 XAML 命名空间,就无法确定 XAML 类型信息。 此时,尚未创建类型实例,但 XAML 架构上下文可能需要从定义程序集和后备类型中查找信息。 例如,为了处理标记 <Party><PartyFavor/></Party>,XAML 架构上下文必须能够确定 PartyContentProperty 的名称和类型,因此还必须知道 PartyPartyFavor 的 XAML 命名空间信息。 在默认 XAML 架构上下文中,静态反射报告在节点流中生成 XAML 类型节点所需的大量 XAML 类型系统信息。

为了从 XAML 节点流生成对象图,用于原始标记并记录在 XAML 节点流中的每个 XAML 前缀都必须存在 XAML 命名空间声明。 此时,系统正在创建实例,并发生真正的类型映射行为。

如果你希望 XAML 架构上下文使用的 XAML 命名空间未在标记中定义,并因此需要预填充 XAML 命名空间信息,则可以使用在 XmlReaderXmlParserContext 中声明 XML 命名空间声明的方法。 然后将该 XmlReader 用作 XAML 读取器构造函数或 XamlServices.Load(XmlReader) 的输入。

与 .NET XAML 服务中的 XAML 命名空间处理相关的另外两个 API 是属性 XmlnsDefinitionAttributeXmlnsPrefixAttribute。 这些属性适用于程序集。 XmlnsDefinitionAttribute 由 XAML 架构上下文用于解释任何包含 URI 的 XAML 命名空间声明。 XmlnsPrefixAttribute 由发出 XAML 的工具使用,以便通过可预测的前缀序列化特定 XAML 命名空间。 有关详细信息,请参阅自定义类型和库的 XAML 相关 CLR 属性

另请参阅