Jump to content

XML to XML transformation question


n00bXSL
 Share

Recommended Posts

Hi, everyone.I am new to this forum and XSL in general. I am wondering if anyone can help me with a problem.I am trying to do an XML to XML transformation with the following input:

<item-1>Item1</item-1><elementA/><item-code-1>123</item-code-1><item-price-2>34.00</item-price-2><elementB/><item-code-2>456</item-code-2><item-price-1>35.00</item-price-1><elementC/><item-2>Item2</item-2>

The output should extract the any of the data on items and create new Item elements in the output xml:

<Item num=1>   <Name>Item1</Name>   <Code>123</Code>   <Price>35.00</Price></Item><Item num=2>   <Name>Item2</Name>   <Code>456</Code>   <Price>34.00</Price></Item>

The problem is, the order of the elements in the incoming xml is not always the same and the number of items are unknown. I have tried sorting the elements first:

<item-code-1>123</item-code-1><item-name-1>Item1</item-name-1><item-price-1>35.00</item-price-1><item-code-2>456</item-code-2><item-name-2>Item2</item-name-2><item-price-2>34.00</item-price-2><elementA/><elementB/><elementC/>

And then do this in my xslt:

<xsl:for-each select="*"><xsl:sort select="substring(name(), string-length(name()))"/><xsl:sort select="name()"/><xsl:if test="starts-with(name(), 'item-code')"><Item><Code><xsl:value-of select="."/></Code></xsl:if><xsl:if test="starts-with(name(), 'item-name')"><Name><xsl:value-of select="."/></Name></xsl:if><xsl:if test="starts-with(name(), 'item-price')"><Price><xsl:value-of select="."/></Price></Item></xsl:if></xsl:for-each>

But the code doesn't like having the <Item> tag incomplete within the first xsl:if statement. I am thinking of building the entire Item element within a single xsl:if statement, but I am not sure how to get the data of the proceeding sibling nodes to do so.Any tips will be much appreciated.

Link to comment
Share on other sites

If you have a control over the XML structure, what is stopping you from manually transforming it properly? Anyway... a plausable solution to the problem would be to enclose the improperly nested tags with disable-output-escaping, like this:

<xsl:text disable-output-escaping="yes"><Item></xsl:text>

However, this doesn't work in firefox. If you were using a server side scripting parser to perform the transformations, then it would be great.In the presented case above... hmm... I'll have to dig deeper maybe, but the first thing that comes to mind is using the linear to tabular data code, then edit the tr and/or td into the desired XML outputs.

Link to comment
Share on other sites

If you have a control over the XML structure, what is stopping you from manually transforming it properly?
In this case, I don't have any control over the incoming xml ordering. The sorting was done within the xslt as well.
In the presented case above... hmm... I'll have to dig deeper maybe, but the first thing that comes to mind is using the linear to tabular data code, then edit the tr and/or td into the desired XML outputs.

Hmmm... Maybe I will give this a try.Thanks for the hints.
Link to comment
Share on other sites

  • 4 months later...

I'm working on a translation of POM files. I have a POM file that has the following as the project stanza.<project xmlns="http://maven.apache.org/POM/4.0.0"'>http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">With the namespace information on the project statement my xsl does nothing. If I remove all the information from project and it looks like this <project> my xsl works as expected. What do I need to do to allow the template in the xsl to process this POM file?

Link to comment
Share on other sites

This is a somewhat complex solution (for the original question). There may be a simpler one. But nonetheless, its worth studying.This XML

<items>   <item-1>Item1</item-1>   <elementA/>   <item-code-1>123</item-code-1>   <item-price-2>34.00</item-price-2>   <elementB/>   <item-code-2>456</item-code-2>   <item-price-1>35.00</item-price-1>   <elementC/>   <item-2>Item2</item-2></items>

This XSLT

<xsl:stylesheet  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="1.0">	<xsl:output method="xml"/>	<xsl:template match="/">		<xsl:for-each select="//*[starts-with(text(),'Item')]">			<xsl:element name="Item">				<xsl:variable name="number" select="substring-after(name(),'-')" />				<xsl:attribute name="num">					<xsl:value-of select="$number" />				</xsl:attribute>								<xsl:element name="Name">					<xsl:value-of select="concat('Item',$number)"/>				</xsl:element>										<xsl:element name="Code">					<xsl:value-of select="//*[contains(name(),concat('-code-',$number))]"/>								</xsl:element>										<xsl:element name="Price">					<xsl:value-of select="//*[contains(name(),concat('-price-',$number))]"/>								</xsl:element>					</xsl:element>			</xsl:for-each>	</xsl:template></xsl:stylesheet>

This result

<?xml version="1.0"?><Item num="1">	<Name>Item1</Name>	<Code>123</Code>	<Price>35.00</Price></Item><Item num="2">	<Name>Item2</Name>	<Code>456</Code>	<Price>34.00</Price></Item>

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...