XML特定节点模板不匹配

时间:2012-02-20 15:13:12

标签: xml templates xslt

我目前正在尝试将XML文档复制到新文档中,并在我去的时候重命名一些节点。然而,我的问题是我的模板没有被击中,只有全局模板是:

  <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>

xml结构类似于此,但由于工作的性质而适应:)

<T>
 <A>
  <B>
  </B>
  <C>
  </C>
 </A>
 <D>
  <E>Data</E>
  <F>Data</F>
 </D>
</T>

在VS2010中运行时,我可以看到它在XML上的F行,但是仍然应用通用模板而不是更具体的模板。任何想法为什么会这样?

2 个答案:

答案 0 :(得分:0)

似乎对我来说很好。我使用了以下样式表:

<?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>

Whicj看起来像你想要的结果。那么你可以提供一些关于哪里出错的更多信息吗?

答案 1 :(得分:0)

这个OP已经揭示了关于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>

将此转换应用于以下XML文档(基于OP承认的命名空间...):

<T xmlns="some:namespace">
    <A>
        <B>   </B>
        <C>   </C>
    </A>
    <D>
        <E>Data</E>
        <F>Data</F>
    </D>
</T>

产生了想要的正确结果

<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元素匹配。