当前位置: 动力学知识库 > 问答 > 编程问答 >

XML Specific node template not matching

问题描述:

I am currently trying to copy out an XML document into a new one and renaming some of the nodes as I go. My issue however is that my templates are not being hit and only the global one is:

 <xsl:template match="node()|@*">

<xsl:copy>

<xsl:apply-templates select="node()|@*"/>

</xsl:copy>

</xsl:template>

and my specific template is (adapted for below):

 <xsl:template match="F">

<G>

<xsl:apply-templates/>

</G>

</xsl:template>

The xml structure is similar to this however adapted due to the nature of the work :)

<T>

<A>

<B>

</B>

<C>

</C>

</A>

<D>

<E>Data</E>

<F>Data</F>

</D>

</T>

When running this through in VS2010 I can see it hit the line of F on the XML however is still applies the general template and not the more specific one. Any ideas why this would be?

网友答案:

This OP has conceiled the most important fact about the XML document -- as he tells us in a later comment, "The XML uses a namespace" ...

Here is a solution to this so late-clarified question:

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

when this transformation is applied on the following XML document (based on the namespace the OP admitted...):

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

the wanted, correct result is produced:

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

Explanation:

The problem in the original code is here:

  <xsl:template match="F">

This template matches an element F that is in no namespace. However all elements of the real XML document are in some undisclosed namespace -- not in no namespace. Therefore, the above template cannot match an F element in no namespace, because no such (F element in no namespace) exists.

The solution is to define the same namespace in the XSLT transformation and to have the template match an F element in that namespace.

网友答案:

Seems to work fine for me. I used following stylesheet :

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

and ran it on your xml code, returning the following :

<?xml version="1.0" encoding="UTF-8"?>
<T>
<A>
    <B>
</B>
    <C>
</C>
</A>
<D>
    <E>Data</E>
    <G>Data</G>
</D>

Whicj looks like the result you want. So can you give a bit more info on where things go wrong ?

分享给朋友:
您可能感兴趣的文章:
随机阅读: