有没有办法在XSL转换期间忽略名称空间?

时间:2009-03-10 13:09:45

标签: xml xslt

在处理XSL转换的服务器上禁用了命名空间检查(因为编写XSL的人不了解命名空间)。我必须对XSL进行更改,但我无法测试它,因为没有定义任何名称空间,即。

而不是

 <xsl:template match="ns:element[position()=1]">...

它有

 <xsl:template match="element[position()=1]">...

因此它与XML中的任何元素都不匹配,因为它们都符合命名空间。

我无法在服务器上测试,因为我无法访问它。修复XSL是没用的,因为必须启用名称空间检查,这将打破所有其他转换。

所以我需要做的是找到一种在XSL转换期间忽略命名空间的方法。我可以访问MSXML,XMLSpy(在这里找不到选项),如果我真的需要,我可以使用C#或类似语言编写代码。

作为最后的手段,我可​​以编写一些正则表达式,但我真的不想走这条路,特别是在处理XML时...

回应有关更多细节的评论:

这是一个Windows 2003虚拟服务器,运行一个Methode Servlet实例(www.eidosmedia.com)。我不知道这个servlet用于执行XSL转换的技术。他们忽略了名称空间,因为最初编写XSL的人不理解它们,并且没有将它们包含在XSL中。所以现在所有的XSL文件(数百个)都没有命名空间。

一次性修复所有这些文件可能是一个有趣的挑战,但这不是我现在所需要的(并且由于所涉及的测试数量,部门经理无论如何都不会同意它)。我想知道的是,是否有可用的工具(或技术)允许我按原样获取这些XSL文件,并使用它们转换相应的XML文档而不考虑命名空间。在我看来,必须存在一个工具,因为编写原始XSL的人必须使用类似的东西来自己测试转换。

3 个答案:

答案 0 :(得分:5)

可以进行转换,以便在“真正”转换之前从输入中删除所有命名空间。但是......我不确定你是否应该这样做。感觉很难看。

<xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="*">
    <xsl:element name="{local-name()}" >
      <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
  </xsl:template>  

  <xsl:template match="@*">
    <xsl:attribute name="{local-name()}">
      <xsl:value-of select="." />
    </xsl:attribute>
  </xsl:template>  

</xsl:stylesheet>

原始答案:

这会是一种选择吗?

<xsl:template match="*[local-name()='element' and position()=1]">...

(正如评论所示 - 它不会)

答案 1 :(得分:1)

我将此作为答案发布,因为它太长而无法作为评论。

我从未听说过的XSLT处理器允许您只是全局忽略输入XML中的命名空间。如果你有无法使用命名空间编写的XSL转换,以及使用它们的XML文档,则必须使用损坏的servlet进行转换,或者预处理XML文档以删除命名空间。

Tomalak发布的转换将会这样做 - 与使用正则表达式不同,它会在不搞砸XML中的其他所有内容的情况下完成。而且要做到这一点也不是很重要。链接变换非常简单。

答案 2 :(得分:0)

正在转换的XML中有多少个名称空间?

如果1可以暂时将该命名空间添加为XSL的默认命名空间吗?好的,这意味着您可能需要更改输出命名空间等,但经过测试,您可以删除这些调整。

如果超过1,则表示命名空间之间没有本地名称冲突。您是否可以调整测试输入XML,以便所有别名指向同一名称空间,然后执行上面的调整。