Excel Office Web Add-Ins清单XML命名空间前缀兼容问题咨询
开发Excel Office Web Add-Ins时,需通过manifest.xml文件描述服务。以下是一个可正常在Excel中打开任务窗格的简单清单:
<?xml version="1.0" encoding="utf-8"?> <OfficeApp xsi:type="TaskPaneApp" xmlns="http://schemas.microsoft.com/office/appforoffice/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0" xmlns:ov="http://schemas.microsoft.com/office/taskpaneappversionoverrides" > <Id>61b854ed-e679-4ae7-9c91-c04e9846f706</Id> <Version>0.0.0.1</Version> <ProviderName>MyProvider</ProviderName> <DefaultLocale>en-US</DefaultLocale> <DisplayName DefaultValue="MyDisplayName" /> <Description DefaultValue="My Description." /> <IconUrl DefaultValue="~remoteAppUrl/Images/Button32x32.png" /> <SupportUrl DefaultValue="http://www.google.com" /> <Hosts> <Host Name="Workbook" /> </Hosts> <DefaultSettings> <SourceLocation DefaultValue="~remoteAppUrl/excel/" /> </DefaultSettings> <Permissions>ReadWriteDocument</Permissions> </OfficeApp>
我将这份清单修改为使用命名空间前缀的版本后,Excel直接忽略它且无任何错误提示,无法正常工作:
<?xml version="1.0" encoding="utf-8"?> <x:OfficeApp xsi:type="x:TaskPaneApp" xmlns:x="http://schemas.microsoft.com/office/appforoffice/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0" xmlns:ov="http://schemas.microsoft.com/office/taskpaneappversionoverrides" > <x:Id>61b854ed-e679-4ae7-9c91-c04e9846f706</x:Id> <x:Version>0.0.0.1</x:Version> <x:ProviderName>MyProvider</x:ProviderName> <x:DefaultLocale>en-US</x:DefaultLocale> <x:DisplayName DefaultValue="MyDisplayName" /> <x:Description DefaultValue="My Description." /> <x:IconUrl DefaultValue="~remoteAppUrl/Images/Button32x32.png" /> <x:SupportUrl DefaultValue="http://www.google.com" /> <x:Hosts> <x:Host Name="Workbook" /> </x:Hosts> <x:DefaultSettings> <x:SourceLocation DefaultValue="~remoteAppUrl/excel/" /> </x:DefaultSettings> <x:Permissions>ReadWriteDocument</x:Permissions> </x:OfficeApp>
从XML规范来看,这两份文件语义完全相同,且都能通过Office清单XML架构验证,但实际运行结果不同。我有两个疑问:
- 我的理解是否正确?Excel应该能处理命名空间前缀,是我转换过程中出错了?
- 我的理解是否错误?Excel仅支持无修饰的XML元素,不允许使用前缀?
(我的最终目标是通过XSLT生成这份清单,但发现不使用命名空间前缀的话实现起来很困难。)
更新
生成正确清单的难点在于,规范的Office清单包含两个(或更多)使用不同默认命名空间的部分。我不知道如何在不使用前缀的情况下通过XSLT完成命名空间转换。(这或许应该单独提一个问题?)
示例如下,<OfficeApp>和<VersionOverrides>元素属于不同的命名空间:
<?xml version="1.0" encoding="UTF-8"?> <OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0" xmlns:ov="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="TaskPaneApp" > ... <Hosts> <Host Name="Workbook" /> </Hosts> ... <VersionOverrides xmlns="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="VersionOverridesV1_0" > <Hosts> <Host xsi:type="Workbook"> </Host> </Hosts> ... </VersionOverrides> </OfficeApp>
问题解答
你的理解部分正确:从XML标准角度,带前缀和不带前缀的命名空间语义等价,且能通过Schema验证,但Excel的Add-in清单解析器存在特殊限制——它仅支持将
http://schemas.microsoft.com/office/appforoffice/1.1作为默认命名空间,不接受使用显式前缀的方式声明该命名空间下的元素。这是因为Office的清单解析逻辑并非完全遵循通用XML规范,它对根元素<OfficeApp>及其子元素的命名空间绑定方式做了硬编码要求,必须使用默认命名空间(无前缀),否则会直接忽略整个清单,且不会给出错误提示。你的第二个疑问结论正确:对于主清单的核心命名空间,Excel确实仅支持无修饰的XML元素,不允许使用前缀。
针对XSLT生成清单的解决方案
针对你提到的多命名空间场景(比如<VersionOverrides>属于另一个命名空间),可以通过XSLT的命名空间重定义和默认命名空间切换来实现,无需使用前缀即可生成符合要求的清单:
- 在XSLT中,为主命名空间(
http://schemas.microsoft.com/office/appforoffice/1.1)设置默认命名空间,确保根元素<OfficeApp>及其子元素无前缀。 - 当处理
<VersionOverrides>及其子元素时,在对应的模板中重新定义默认命名空间为http://schemas.microsoft.com/office/taskpaneappversionoverrides,同时保留其他命名空间的前缀声明(比如xsi、bt)。
示例XSLT片段:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://schemas.microsoft.com/office/appforoffice/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0" xmlns:ov="http://schemas.microsoft.com/office/taskpaneappversionoverrides" exclude-result-prefixes="xsl ov"> <!-- 处理根元素OfficeApp,默认命名空间已设置 --> <xsl:template match="/"> <OfficeApp xsi:type="TaskPaneApp"> <!-- 生成主清单的子元素 --> <Id>61b854ed-e679-4ae7-9c91-c04e9846f706</Id> <Version>0.0.0.1</Version> <!-- ... 其他主清单元素 ... --> <!-- 调用VersionOverrides的模板 --> <xsl:call-template name="VersionOverrides"/> </OfficeApp> </xsl:template> <!-- 处理VersionOverrides,切换默认命名空间 --> <xsl:template name="VersionOverrides"> <xsl:element name="VersionOverrides" namespace="http://schemas.microsoft.com/office/taskpaneappversionoverrides"> <xsl:attribute name="xsi:type">VersionOverridesV1_0</xsl:attribute> <!-- 生成VersionOverrides下的子元素,默认命名空间已切换 --> <Hosts> <Host xsi:type="Workbook"/> </Hosts> <!-- ... 其他VersionOverrides元素 ... --> </xsl:element> </xsl:template> </xsl:stylesheet>
通过这种方式,生成的XML会自动为<OfficeApp>使用默认主命名空间,为<VersionOverrides>使用其专属的默认命名空间,完全符合Excel的清单要求,同时无需在最终输出中使用命名空间前缀。
内容的提问来源于stack exchange,提问作者Chris C.

