我正在使用call-template,其源代码如下所示。
来源:
<Content>
<first>
<text>
Text
</text>
<link xmlns="Some namespace">
<AA>abcd</AA>
<BB>hi all</BB>
</link>
</first>
<second>
<link xmlns="Some other namespace">
<AA>abcd1</AA>
<BB>hi all21</BB>
</link>
</second>
<three>
<link xmlns="other namespace">
<AA>abcd2</AA>
<BB>hi all33</BB>
</link>
</three>
</Content>
XSLT编写:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:n1="Some namespace" xmlns:n2="Some other namespace" xmlns:n3="other namespace">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="Content">
<xsl:call-template name="process">
<xsl:with-param name="item" select="first/n1:link" />
</xsl:call-template>
<xsl:call-template name="process">
<xsl:with-param name="item" select="second/n2:link" />
</xsl:call-template>
<xsl:call-template name="process">
<xsl:with-param name="item" select="three/n3:link" />
</xsl:call-template>
</xsl:template>
<xsl:template name="process">
<xsl:param name="item" />
<xsl:value-of select="$item/AA" />
</xsl:template>
</xsl:stylesheet>
我得到空白输出。我知道原因,因为我没有附加名称空间前缀。像那样的“n1:A”。
因为即将到来多次。我写了一个模板并在需要的地方调用。但每个链接的名称空间是不同的。如何修改我的代码,以便我可以重用模板“进程”。
任何人都可以提供帮助,如何相应地修改“进程”模板以处理不同的命名空间但结构相同。
谢谢。
答案 0 :(得分:0)
而不是这样做
<xsl:value-of select="$item/AA" />
您可以将表达式更改为此
<xsl:value-of select="$item/*[local-name() = 'AA'][namespace-uri()=namespace-uri($item)]" />
即。检查没有名称空间的名称是'AA',并且它与父元素具有相同的名称空间。这意味着如果你在'link'元素中有另一个'AA'元素与不同的命名空间,它就不会被拾取。
答案 1 :(得分:0)
值得指出的是,这是一个设计糟糕的XML文档。每当您看到有人创建两个名称空间N1和N2,使得N1中的本地名称与N2中的本地名称相同时,您应该检测到设计气味。他们使XML更难以处理。
当我看到这种输入时(如果人们错误地更改了词汇表第2版的名称空间URI,有时会出现这种情况)我通常认为处理它的最佳方法是编写一个第一阶段是规范化命名空间,以便“真正的”处理逻辑不必像代码一样处理多个命名空间,这总是看起来像意大利面。