使用具有非默认命名空间和XSL文件的XML文件时,编写.NET将理解的XPath表达式的正确方法是什么?

时间:2013-02-04 15:33:41

标签: .net xml xslt xpath xslcompiledtransform

我知道当涉及到.NET(或者至少是我正在使用的.NET版本)时,如果我想查询具有非默认命名空间的XML文档中的数据,我有至少有两个选择:

1. use the local-name() function before referencing a
node in the xpath expression.

2. work with the XmlNamespaceManager class and assign prefixes
that then need to be referenced in the xpath expression.

最近我一直在使用XSLCompiledTransform类,并且在从具有非默认命名空间的XML文件中读取数据时遇到了类似的问题。

由于将要编写实际XSL文件的人可能不知道他们需要使用local-name()函数,并且无法控制他们将使用的XML文件,我能做什么,代码,为了忍受XSLCompiledTransform类正确解释表单的xpath表达式(/ node0 / node1 / node2 / etc)?

2 个答案:

答案 0 :(得分:2)

通常,正确的做法是为将要使用的命名空间分配前缀并使用它们,无论它是在XSLT中还是在XmlNamespaceManager中。 local-name()绕过命名空间是相当hackish。

我对你问题的后半部分和你的要求感到有些困惑。你将在XslCompiledTransform类中使用什么样的XPath?你是指XSLT本身的XPath吗?

关于命名空间的事情是,只要URI匹配,前缀就可以是任何东西。因此,您对“无法控制他们将使用的XML文件”的评论可能是无根据的。例如,如果输入XML如下所示:

<aa:root xmlns:aa="http://my.namespace.com">
   <aa:child>Hello!</aa:child>
</aa:root>

您可以拥有这样的XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:bb="http://my.namespace.com">
    <xsl:template match="bb:root">
       <xsl:value-of select="bb:child" />
    </xsl:template>
</xsl:stylesheet>

并且一切都会正常工作,因为命名空间URI匹配。这比使用local-name() s散布XSLT要好得多。

答案 1 :(得分:2)

如果编写XSLT代码的人不知道XML实例中将使用哪些命名空间,那么他们就会在黑暗中工作 - 它实际上完全相同(实际上完全相同),因为不知道本地名称会是什么使用,因为元素名称分为两部分,一个URI和一个本地名称,你需要知道它们。如果您事先不知道全名,您可以随时通过通配符选择元素并发现它们的名称 - 这实际上就是您在使用local-name()时所做的事情 - 但这很难。