XSL: Error when trying to copy node and attributes again for output xml

I'm using Visual studios to debug an xsl file with a given xml
I'm simply copying the entire node alongside it's attributes.

But i keep getting this error "Attribute and namespace nodes cannot be added to the parent element after a text, comment, pi, or sub-element node has already been added."



<?xml version = "1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version = "1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" encoding="UTF-8"/>

This is the xsl
  <xsl:template match="Fare">
    <Fare>
       		<xsl:copy-of select="./@*"/>
					<xsl:for-each select="./*">
                                              <xsl:copy-of select="."/>
					     <xsl:copy-of select="./@*"/>			<!--If I comment this line it works, but why?-->	
					</xsl:for-each>
		</Fare>			
    </xsl:template>
</xsl:stylesheet>

Open in new window



and the input file
<Fare FareType="PUBL" TravelerCount="1" TotalPrice="17968" FareNumber="1" Source="RT" SourceRef="XXYZ">
	<CurrencyCode NumberOfDecimals="2">USD</CurrencyCode>
	<Trav TypeRequested="ADT" TypePriced="ADT" TypeCount="1" TypeTotalPrice="17968">
		<Price Total="17968">
			<Base Amount="12200"/>
			<Taxes Amount="5768">
				<Tax Amount="712">
					<Designator>US</Designator>
				</Tax>
			</Taxes>
		</Price>
	</Trav>
</Fare>

Open in new window

badtz7229Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

zc2Commented:
You are copying attributes ( @* ) but there is no output element you to can append the attributes to.

In XSLT there are two "copy" directives: <xsl:copy> and <xsl:copy-to>.
The first one creates an empty element, in which you could add additional attributes and/or children.
And in your case, <xsl:copy> probably more suitable. I can not tell exactly, because I don't know what output XML structure you want to get in the result.
Check out this code:
<?xml version = "1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version = "1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" encoding="UTF-8"/>

  <xsl:template match="Fare">
    <Fare>
       		<xsl:copy-of select="./@*"/>
			<xsl:for-each select="./*">
                         <xsl:copy>
			        <xsl:copy-of select="./@*"/>	<!--No more errors-->	
                         </xsl:copy>    
			</xsl:for-each>
	</Fare>			
    </xsl:template>
</xsl:stylesheet>
                                  

Open in new window

0
badtz7229Author Commented:
@zc2 - if i use ur xsl it does not copy the inner nodes (price)
0
zc2Commented:
Copy the inner nodes using <xsl:copy-of select="*"/>

<?xml version = "1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version = "1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" encoding="UTF-8"/>

<xsl:template match="Fare">
    <Fare>
   		<xsl:copy-of select="./@*"/>
		<xsl:for-each select="./*">
             <xsl:copy>
		        <xsl:copy-of select="./@*"/>
                <xsl:copy-of select="*"/> 
             </xsl:copy>    
		</xsl:for-each>
	</Fare>			
</xsl:template>
</xsl:stylesheet>

Open in new window

0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

badtz7229Author Commented:
@zc2:

your solution does not include the   value inside CurrencyCode
it only copies attributes but not value of node itself
0
badtz7229Author Commented:
so my original question remains, why is it when i commented out that line in code it works but with it active it fails?
0
zc2Commented:
Please replace the line 11 with the following:
<xsl:copy-of select="*|text()"/>
0
zc2Commented:
In your original XSL, this statement
<xsl:copy-of select="./@*"/>
copies all the current input node attributes to the current output node.
The attributes have to be added to the output element before all other children are added.
Once you added a child node such as a child element or an inner text node you can not add attributes anymore.

For an instance, your XSL has two such statements, at the line 8 and the line 11.
The one at the line 8 works, because there is an active output element ( <Fare> ) and it is being declared and no children were added yet.
The one at the line 11 does not work, because you add children on the line 10 and attributes can not be added to the current output element (still <Fare> ) anymore.

Hope my explanation is understandable.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
badtz7229Author Commented:
@zc2 - thanks that worked and i understand
0
zc2Commented:
You are welcome
0
badtz7229Author Commented:
thanks
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
CSS

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.