Xslt 输入XML的动态命名空间

Xslt 输入XML的动态命名空间,xslt,xpath,namespaces,Xslt,Xpath,Namespaces,我已经搜索了很多关于动态设置名称空间的帖子,但它们似乎都涉及到设置输出XML的名称空间 我遇到的问题是输入XML的名称空间(定义在根目录下,对于所有子节点都是相同的)不同,并且相同的样式表需要能够处理这两个输入 例如,一个输入XML是: <root xmlns="aaa"> <body>xxx</body> </root> <root xmlns="bbb"> <body>yyy</body>

我已经搜索了很多关于动态设置名称空间的帖子,但它们似乎都涉及到设置输出XML的名称空间

我遇到的问题是输入XML的名称空间(定义在根目录下,对于所有子节点都是相同的)不同,并且相同的样式表需要能够处理这两个输入

例如,一个输入XML是:

<root xmlns="aaa">
    <body>xxx</body>
</root>
<root xmlns="bbb">
    <body>yyy</body>
</root>
但是,一旦第二个输入XML被转换,它当然就无法工作

我可以定义另一个名称空间,例如

xmlns:two="bbb"
但在正确的时间使用该名称空间的唯一方法是复制所有XSLT代码,并使用另一个名称空间作为所有XPath的前缀(即使这样,我仍然需要确定使用哪一组XPath,哪一组可能很有趣..)

我的样式表当前使用以下XPath:

%lt;SOMETHING&gt;
<xsl:value-of select="one:body" />
%lt;/SOMETHING&gt;
%lt;某物
%lt/某物
如您所见,它使用“一”名称空间前缀。不管名称空间如何,是否有方法只获取“body”标记的值?正如在下面的评论中提到的,尽管我知道它们是基于名称空间的不同元素,但我知道每个元素中的信息都是相同的,所以我可以这样对待它们

我看到过关于使用xsl:element和namespace属性的文章,但从我所知道的,它只定义了输出XML的名称空间,而不是输入。(更糟糕的是,我输出的实际上是转义XML,例如%lt;SOMETHING>,因此我无论如何都不能使用xsl:element)

我目前的解决方案(自从发布这篇文章以来)是在主样式表中包含两个额外的样式表。每一行特定于名称空间“1”或名称空间“2”,XPath的每一行都使用相关的名称空间前缀

我希望有一种方法可以避免两个除了名称空间前缀之外几乎完全相同的单独样式表


提前感谢。

我建议您定义两个名称空间,然后使用以下路径:

one:body | two:body
来处理源XML中的元素


例如,而不是:

<xsl:value-of select="one:body" />
<xsl:template match="one:body">
<xsl:template match="two:body">

使用:


如果我没记错的话,您希望忽略元素的名称空间来处理XML。实际上,名称空间的意义在于区分来自不同上下文的元素。因此,从XML的角度来看,
完全无关,只是它们碰巧有相同的名称

如果您仍想这样做,请不要:

<xsl:value-of select="one:body" />
<xsl:template match="one:body">
<xsl:template match="two:body">
成功了

<xsl:template match="*[local-name()='body']">

相反,你最好说

<xsl:template match="*[namespace-uri()='aaa' or namespace-uri()='bbb'][local-name()='body']">



等等如果,如dret所述,您提前知道所有可能的名称空间。

如我所写!而不是

<xsl:value-of select="one:body" />

你可以写

<xsl:value-of select="*[local-name()='body']" />

或者,如果您有XPath2.0,那么

<xsl:value-of select="*:body" />


这不是一个好答案。名称空间被假定存在是有原因的。忽略它们不是好的实践。忽略名称空间可能不是好的实践,但正如我得到的,这就是Neil Belch要求的。我理解这个问题的方式,他希望以相同的方式处理两个已知的名称空间-这与以相同的方式处理任何名称空间不同。这只是他给出的一个示例。忽略它们听起来确实像是一种选择,不幸的是,我们正在为一个我们没有太多控制权的系统编写样式表,因此我们可能不得不违反惯例来回避问题。我理解您所说的,不同名称空间中的相同元素名是完全不同的元素,但出于我的目的,它们包含相同的信息。但是-在XPath定义中如何使用本地名称函数?我编辑了我的问题,希望能提供更多关于我的意思的详细信息。除了显示输入文档外,还请显示您希望从转换中获得的输出。这比仅使用本地名称要好得多,但只有在提前知道预期的名称空间(并且没有太多名称空间)时才有效。这看起来是最有希望的解决方案-我知道这不是最佳做法,但我可以做出假设,例如,不同名称空间中名为“body”的两个标记可以被视为具有相同的数据。测试完成后,我会反馈/接受/等等,谢谢。
<xsl:template match="*[namespace-uri()='aaa' or namespace-uri()='bbb'][local-name()='body']">
<xsl:template match="*[namespace-uri()='aaa' or namespace-uri()='bbb' or namespace-uri()='ccc'][local-name()='body']">
<xsl:value-of select="one:body" />
<xsl:value-of select="*[local-name()='body']" />
<xsl:value-of select="*:body" />