XML特定的节点模板不匹配
我目前正在尝试将一个XML文档复制到一个新文档中,并在运行时重命名一些节点。但我的问题是,我的模板没有被击中,只有全局模板是:XML特定的节点模板不匹配,xml,templates,xslt,Xml,Templates,Xslt,我目前正在尝试将一个XML文档复制到一个新文档中,并在运行时重命名一些节点。但我的问题是,我的模板没有被击中,只有全局模板是: <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> 我的具体模板是(适用于以下内容): x
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
我的具体模板是(适用于以下内容):
xml结构与此类似,但由于工作的性质而进行了调整:)
资料
资料
当在VS2010中运行这个过程时,我可以看到它在XML上碰到了F行,但是它仍然应用常规模板,而不是更具体的模板。你知道为什么会这样吗?对我来说似乎很好。我使用了以下样式表:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="F">
<G>
<xsl:apply-templates/>
</G>
</xsl:template>
</xsl:stylesheet>
并在xml代码上运行,返回以下内容:
<?xml version="1.0" encoding="UTF-8"?>
<T>
<A>
<B>
</B>
<C>
</C>
</A>
<D>
<E>Data</E>
<G>Data</G>
</D>
资料
资料
看起来像是你想要的结果。那么,您能提供一些关于哪里出了问题的更多信息吗?这篇文章关注了关于XML文档的最重要的事实,正如他在后面的评论中告诉我们的,“XML使用了一个名称空间” 这是一个如此晚才澄清的问题的解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="some:namespace" xmlns="some:namespace"
exclude-result-prefixes="x">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="x:F">
<G>
<xsl:apply-templates/>
</G>
</xsl:template>
</xsl:stylesheet>
<T xmlns="some:namespace">
<A>
<B />
<C />
</A>
<D>
<E>Data</E>
<G>Data</G>
</D>
</T>
当此转换应用于以下XML文档时(基于OP允许的命名空间…):
资料
资料
生成所需的正确结果:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="some:namespace" xmlns="some:namespace"
exclude-result-prefixes="x">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="x:F">
<G>
<xsl:apply-templates/>
</G>
</xsl:template>
</xsl:stylesheet>
<T xmlns="some:namespace">
<A>
<B />
<C />
</A>
<D>
<E>Data</E>
<G>Data</G>
</D>
</T>
资料
资料
说明:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="some:namespace" xmlns="some:namespace"
exclude-result-prefixes="x">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="x:F">
<G>
<xsl:apply-templates/>
</G>
</xsl:template>
</xsl:stylesheet>
<T xmlns="some:namespace">
<A>
<B />
<C />
</A>
<D>
<E>Data</E>
<G>Data</G>
</D>
</T>
原始代码中的问题如下:
<xsl:template match="F">
此模板匹配不在命名空间中的元素F
。然而,真正XML文档的所有元素都在某个未公开的名称空间中,而不是在无名称空间中。因此,上面的模板无法匹配没有命名空间的F
元素,因为不存在这样的(F
元素,没有命名空间)
解决方案是在XSLT转换中定义相同的名称空间,并使模板匹配该名称空间中的
F
元素。在VS2010中使用断点运行XSLT时,它会到达我要查找的节点,并使用默认模板读取它。还复制了您的模板,并尝试接收相同的问题。XML使用名称空间,这会对流程产生任何影响吗?我在xslt中声明的ns与在xml im转换中声明的ns相同,因此我不会认为这是错误的that@Mike:您向我们隐藏了一个最重要的信息--节点位于名称空间中(默认值?)。即使是这样,你也应该投反对票(只是说说而已)。请编辑问题并提供一个真正的XML文档,这样人们就可以自己重新编写问题了!不是默认的名称空间,如果我有线索的话,我会说它很重要,很明显,这将很难得到回应,因为我不能透露实际数据,因为它与工作相关,因此是保密的。如果你觉得有必要的话,请随时否决我的投票。这是一个很好的网站欢迎:)名称空间可能是问题的原因吗?@Mike:当然,名称空间是原因。请看我的答案。很抱歉省略了细节,但我对XSL的经验非常少。不过它解决了这个问题。@Mike:细节很重要。否则我们可以解释恶劣天气的任何问题。