使用xsl命名空间别名时如何处理命名空间版本问题

时间:2011-10-04 21:29:10

标签: xslt

我有一个xslt文件,如:

   <?xml version="1.0" encoding="utf-8"?>
   <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt"
      xmlns:MM="http://schemas.microsoft.com/sqlserver/ManagementModel/Serialization/2011/09"
      xmlns:RE="http://schemas.microsoft.com/sqlserver/RelationalEngine/Serialization/2011/09"
      xmlns:dac="urn:dacFunctions"
      exclude-result-prefixes="msxsl">
   <xsl:output method="xml" indent="yes"/>

问题是我们可能会从http://schemas.microsoft.com/sqlserver/ManagementModel/Serialization/2011/09 to http://schemas.microsoft.com/sqlserver/ManagementModel/Serialization/2011/10

更改名称空间

对于新的xmls,那么旧的xslt无法在不更改标头的情况下处理新的xml文件。我想知道我们是否可以通过智能方式让xlst处理所有版本的命名空间。

2 个答案:

答案 0 :(得分:1)

  

问题是我们可能会更改命名空间   http://schemas.microsoft.com/sqlserver/ManagementModel/Serialization/2011/09   至   http://schemas.microsoft.com/sqlserver/ManagementModel/Serialization/2011/10

     

对于新的xmls,那么旧的xslt无法处理新的xml文件   没有改变标题。我想知道我们是否可以有一个聪明的方法   允许一个xlst处理所有版本的命名空间。

没有一般方法,但如果存在某些限制,可以采取措施。

假设

  1. 属于命名空间"http://schemas.microsoft.com/sqlserver/ManagementModel/Serialization/2011/09"的所有名称都以"mm:"为前缀

  2. 前缀"mm:"仅用于与同一名称空间相关联。

  3. 您可以通过以下方式实现namespace-uri独立性

    在任何Xpath表达式中,将名称(例如someName)称为:

    *[starts-with(name(), 'mm:')]
    

    并且在极少数情况下,您可能在此命名空间中具有属性名称(不建议使用属性):

    @*[starts-with(name(), 'mm:')]
    

答案 1 :(得分:0)

我首选的方法是预处理文档(通常使用另一个XSLT转换),以便它们使用一致的命名空间。预处理样式表非常简单,通过这种方式,您可以避免使用大量复杂的条件代码来混淆主样式表。此外,预处理代码完全可重用;你可以在任何管道中使用它。

如果你需要更高的性能,你可以在XML解析器和变换器之间插入的SAX过滤器中进行预处理,在那里它几乎不需要任何费用。

(我还建议人们避免将版本信息打包到命名空间URI中,但是没有告诉微软......)