匹配具有命名空间属性的 XML 元素时遇到问题
Posted
技术标签:
【中文标题】匹配具有命名空间属性的 XML 元素时遇到问题【英文标题】:Trouble matching XML elements that has namespace attribute 【发布时间】:2011-04-06 15:00:40 【问题描述】:如果我要使用 xslt 将一段文本插入到下面的 xml 中,条件语句会是什么样子?
<items xmlns="http://mynamespace.com/definition">
<item>
<number id="1"/>
</item>
<item>
<number id="2"/>
</item>
<!-- insert the below text -->
<reference>
<refNo id="a"/>
<refNo id="b"/>
</reference>
<!-- end insert -->
</items>
这就是我的xsl此刻的样子(条件不对……):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://mynamespace.com/definition"
version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="addRef">
<reference>
<refNo id="a"/>
<refNo id="b"/>
</reference>
</xsl:param>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- here is where the condition got stuck... -->
<xsl:template match="/items[namespace-url()=*]/item[position()=last()]">
<xsl:call-template name="identity"/>
<xsl:copy-of select="$addRef"/>
</xsl:template>
</xsl:stylesheet>
我想在 bottom-most 之后添加参考部分,但我不知道如何绕过匹配具有(显式)命名空间的元素。
谢谢。
【问题讨论】:
【参考方案1】:解决这个问题的更好、更优雅的方法是为您的命名空间使用前缀。我更喜欢使用 null 默认命名空间并为所有已定义的命名空间使用前缀。
匹配fn:local-name()
将匹配所有命名空间中节点的本地名称。如果为命名空间使用前缀my:item[last()]
,则匹配条件中需要的所有内容。
输入:
<?xml version="1.0" encoding="UTF-8"?>
<items xmlns="http://mynamespace.com/definition">
<item>
<number id="1"/>
</item>
<item>
<number id="2"/>
</item>
</items>
XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:my="http://mynamespace.com/definition">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="addRef">
<!-- We set the default namespace to your namespace for this
certain result tree fragment. -->
<reference xmlns="http://mynamespace.com/definition">
<refNo id="a"/>
<refNo id="b"/>
</reference>
</xsl:param>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="my:item[last()]">
<xsl:call-template name="identity"/>
<xsl:copy-of select="$addRef"/>
</xsl:template>
</xsl:stylesheet>
输出:
<?xml version="1.0" encoding="UTF-8"?>
<items xmlns="http://mynamespace.com/definition">
<item>
<number id="1"/>
</item>
<item>
<number id="2"/>
</item>
<reference>
<refNo id="a"/>
<refNo id="b"/>
</reference>
</items>
【讨论】:
【参考方案2】:试试这个:
match="//*[local-name()='items']/*[local-name()='item'][position()=last()]"
【讨论】:
以上是关于匹配具有命名空间属性的 XML 元素时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章