Charla
Charla

Reputation: 33

How to move specific XML nodes by using XSL

I have an XML document:

<Root>
<ANode>
    <FirstSubNode>value1</FirstSubNode>
    <SecondSubNode>value2</SecondSubNode>
</ANode>

<ANode>
    <FirstSubNode>value3</FirstSubNode>
    <SecondSubNode>value4</SecondSubNode>
</ANode>

<ANode>
    <FirstSubNode>value5</FirstSubNode>
    <SecondSubNode>value6</SecondSubNode>
</ANode> </Root>

Now I want to move FirstSubNode to another new node:

<Root>
<ANode>
    <SecondSubNode>value2</SecondSubNode>
</ANode>

<ANode>
    <SecondSubNode>value4</SecondSubNode>
</ANode>

<ANode>
    <SecondSubNode>value6</SecondSubNode>
</ANode>

<BNode>
    <FirstSubNode>value1</FirstSubNode>
    <FirstSubNode>value3</FirstSubNode>
    <FirstSubNode>value5</FirstSubNode>
</BNode></Root> 

My XSL file, duto some reasons, I have to use output "text" format.

<xsl:output method="text" version="1.0" encoding="UTF-8"/>

<xsl:template match="*">
    <xsl:text>&lt;</xsl:text>
    <xsl:value-of select="local-name()"/>
    <xsl:for-each select="@*">
        <xsl:text> </xsl:text>
        <xsl:value-of select="name()"/>
        <xsl:text>="</xsl:text>
        <xsl:value-of select="."/>
        <xsl:text>"</xsl:text>
    </xsl:for-each>
    <xsl:text>&gt;</xsl:text>
    <xsl:apply-templates select="node()"/>
    <xsl:text>&lt;/</xsl:text>
    <xsl:value-of select="local-name()"/>
    <xsl:text>&gt;</xsl:text>
</xsl:template>

<xsl:template match="/Root">
    <xsl:text>&lt;Root&gt;</xsl:text>
    <xsl:apply-templates select="node()"/>

    <xsl:if test="ANode">
        <xsl:text>&lt;BNode&gt;</xsl:text>
        <xsl:for-each select="ANode">
            <xsl:copy>
                <xsl:apply-templates select="FirstSubNode"/>
            </xsl:copy>
        </xsl:for-each>
        <xsl:text>&lt;/BNode&gt;</xsl:text>
    </xsl:if>
    <xsl:text>&lt;/Root&gt;</xsl:text>
</xsl:template>

<xsl:template match="/Root/ANode/FirstSubNode"/>

the appiled XML skips all FirstSubNode... I don't know what's wrong. Can someone help me out? thanks!

<Root>
<ANode>
    <SecondSubNode>value2</SecondSubNode>
</ANode>

<ANode>
    <SecondSubNode>value4</SecondSubNode>
</ANode>

<ANode>
    <SecondSubNode>value6</SecondSubNode>
</ANode><BNode></BNode></Root>

Upvotes: 0

Views: 95

Answers (2)

michael.hor257k
michael.hor257k

Reputation: 117018

This is completely nuts, but if you really must:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" version="1.0" encoding="UTF-8"/>

<xsl:template match="*">
    <xsl:text>&lt;</xsl:text>
    <xsl:value-of select="local-name()"/>
    <xsl:for-each select="@*">
        <xsl:text> </xsl:text>
        <xsl:value-of select="name()"/>
        <xsl:text>="</xsl:text>
        <xsl:value-of select="."/>
        <xsl:text>"</xsl:text>
    </xsl:for-each>
    <xsl:text>&gt;</xsl:text>
    <xsl:apply-templates select="node()"/>
    <xsl:text>&lt;/</xsl:text>
    <xsl:value-of select="local-name()"/>
    <xsl:text>&gt;</xsl:text>
</xsl:template>

<xsl:template match="/Root">
    <xsl:text>&lt;Root&gt;</xsl:text>
        <xsl:apply-templates select="ANode"/>
        <xsl:text>&lt;BNode&gt;</xsl:text>
            <xsl:apply-templates select="ANode/FirstSubNode"/>
        <xsl:text>&lt;/BNode&gt;</xsl:text>
    <xsl:text>&lt;/Root&gt;</xsl:text>
</xsl:template>

<xsl:template match="ANode">
    <xsl:text>&lt;ANode&gt;</xsl:text>
        <xsl:apply-templates select="SecondSubNode"/>
    <xsl:text>&lt;/ANode&gt;</xsl:text>
</xsl:template>

</xsl:stylesheet>

Upvotes: 0

hek2mgl
hek2mgl

Reputation: 158060

You can use the following xsl stylesheet:

<?xml version="1.0"?>

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <Root>
      <xsl:for-each select="//ANode">
        <ANode>
            <SecondSubNode><xsl:value-of select="SecondSubNode"/></SecondSubNode>
        </ANode>
      </xsl:for-each>
        <BNode>
      <xsl:for-each select="//ANode">
            <FirstSubNode><xsl:value-of select="FirstSubNode"/></FirstSubNode>
      </xsl:for-each>           
        </BNode>
  </Root>
</xsl:template>

</xsl:stylesheet> 

Upvotes: 1

Related Questions