How do I insert conditional elements in target document?

D

dmc

Can anyone suggest an elegant solution for this problem? I have a
source document as follows:

<Object Type="Type1">
<Attribute_A>ValueA</Attribute_A>
<Attribute_B>ValueB</Attribute_B>
</Object>

<Object Type="Type2">
<Attribute_A>ValueA</Attribute_A>
<Attribute_B>ValueB</Attribute_B>
</Object>

The schema for my destination document requires the end result to be:

<Object_Type_1>
<Type1AttributeA>ValueA</Type1AttributeA>
<Type1AttributeB>ValueB<Type1AttributeB>
</Object_Type_1>

<Object_Type_2>
<Type2AttributeA>ValueA</Type2AttributeA>
<Type2AttributeB>ValueB<Type2AttributeB>
</Object_Type_2>

The problem is that the element names, and their structure and
children elements
are different depending on the Type of the source elements.

I could use a lookup for the <Object_Type...> elements. This works
very well if only the name
of teh target element changes, but this gets very cumbersome
for managing the child elements and sub-trees. Any help greatly
appreciated.
 
J

Joe Kesselman

What language are you working in? The best solution depends on the tools
you have available.
 
P

p.lepin

dmc said:
Can anyone suggest an elegant solution for this problem?
I have a source document as follows:

<Object Type="Type1">
<Attribute_A>ValueA</Attribute_A>
<Attribute_B>ValueB</Attribute_B>
</Object>

<Object Type="Type2">
<Attribute_A>ValueA</Attribute_A>
<Attribute_B>ValueB</Attribute_B>
</Object>

The schema for my destination document requires the end
result to be:

<Object_Type_1>
<Type1AttributeA>ValueA</Type1AttributeA>
<Type1AttributeB>ValueB<Type1AttributeB>
</Object_Type_1>

<Object_Type_2>
<Type2AttributeA>ValueA</Type2AttributeA>
<Type2AttributeB>ValueB<Type2AttributeB>
</Object_Type_2>

The problem is that the element names, and their
structure and children elements are different depending
on the Type of the source elements.

You probably have a reason you're doing something like
this, but, frankly, judging from the example given, the
design looks quite awful.
I could use a lookup for the <Object_Type...> elements.
This works very well if only the name of teh target
element changes, but this gets very cumbersome for
managing the child elements and sub-trees. Any help
greatly appreciated.

You failed to mention it, but I presume you're using some
sort of DOM or SAX API. Now, it's certainly possible to do
it this way, BUT. If you have an API to some sort of XSLT
processor, -- well, XSLT is quite well-suited to this kind
of processing.

This transformation works for your sample document:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- identity -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- exclusions -->
<xsl:template match="Object">
<xsl:variable name="elt-name">
<xsl:call-template name="make-obj-elt-name"/>
</xsl:variable>
<xsl:element name="{$elt-name}">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
<xsl:template name="make-obj-elt-name">
<xsl:value-of select="local-name()"/>
<xsl:text>_Type_</xsl:text>
<xsl:value-of select="substring-after(@Type,'Type')"/>
</xsl:template>
<xsl:template match="@Type[parent::Object]"/>
<xsl:template
match="*[substring-before(local-name(),'_')]">
<xsl:variable name="elt-name">
<xsl:call-template name="make-attr-elt-name"/>
</xsl:variable>
<xsl:element name="{$elt-name}">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
<xsl:template name="make-attr-elt-name">
<xsl:value-of select="../@Type"/>
<xsl:value-of
select="substring-before(local-name(),'_')"/>
<xsl:value-of
select="substring-after(local-name(),'_')"/>
</xsl:template>
</xsl:stylesheet>

Note that it's unaware of namespaces.
 
D

dmc

Thanks for the replies.

Sorry - I forgot to mention the important things: I am trying to write
an XSLT stylesheet to do this.

The example was really trying to extract the essence of the problem but
I'm afraid I over simplified - the actual designs are somewhat more
complex and the element names are quite different. In any case your
solution is very clever and has given me an idea that I'd like to play
with, thanks.

I left out namespace stuff for clarity.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,007
Messages
2,570,266
Members
46,863
Latest member
montyonthebonty

Latest Threads

Top