Solved

Using XSLT to convert XML configuration files

Posted on 2012-03-26
6
27 Views
Last Modified: 2016-06-23
Hello

I have XML configuration files with the following (simplified) flat structure :
<MyEthernet Activity="true" DefaultGateway="192.168.0.253" PortNumber="1" EthId="IDa2"/>             
<MyEthernet Activity="true" DefaultGateway="193.168.0.253" PortNumber="2" EthId="IDa4"/>
<MyStreamer Activity="true" DestIpAddress="239.0.0.1" RtpId="IDa3" EthRef="IDa2"/>
...

Open in new window

I would like to convert like this:
<MyEthernet Activity="true" DefaultGateway="192.168.0.253" PortNumber="1" EthId="IDa2">             
   <MyStreamer Activity="true" DestIpAddress="239.0.0.1" RtpId="IDa3"/>
</MyEthernet>
<MyEthernet Activity="true" DefaultGateway="193.168.0.253" PortNumber="2" EthId="IDa4"/>

Open in new window


Can it be done using xslt and template matching? I used it before to match/correct single values, but never to move around tags.
0
Comment
Question by:FabClement
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
6 Comments
 
LVL 60

Accepted Solution

by:
Geert Bormans earned 500 total points
ID: 37765199
You can easily do this using XSLT.

Just use a key that indexes the MyStreamer elements by their @EthRef

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:key name="str" match="MyStreamer" use="@EthRef"/>
    
    <xsl:template match="MyEthernet">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates select="key('str', @EthId)" mode="inner"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="MyStreamer"/>

    <xsl:template match="MyStreamer" mode="inner">
        <xsl:copy>
            <xsl:copy-of select="@*[not(name() = 'EthRef')]"/>
        </xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>

Open in new window


You might need to add a template for the root element
(and you might hit an issue with a default namespace on the root element)
0
 
LVL 1

Expert Comment

by:StarbucksDrinker
ID: 38869650
XSLT will not process multiple root elements.  If you can wrap your config nodes inside one root (called anything, as long as it's different from your existing nodes), then wrap your <xsl:template match="MyEthernet"> inside <xsl:template match="/"> and you should be good to go!
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 38870067
Hi Starbucksdrinker.
I think you simply did not have enough Starbucks today :-)
You can not wrap an xsl:template inside another xsl:template
that simply is illegal XSLT

You are right, in order to have wellformed XML there needs to be a container root element.
But you are wrong again in the "called anything but... " There is no reason at all why the root element needs to have a different name. As long as the match statement in the xsl:template is specific enough to differentiate between match="/MyEthernet" for the root

You can have a template match="/" or match="/MyEthernet"
and inside there call out for matching nodes against the other templates
by using xsl:apply-templates inside a template.
But my example shows everything the original poster needs to get started

Brings me to the point... when will this question be closed?
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 41666104
This is an excellent example of adding hierarchy to a flat XML, based on ID and reference IDs (prim key foreign key relation so to speak)
The solution is relevant in a general sense
Please accept https:#a37765199
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The Confluence of Individual Knowledge and the Collective Intelligence At this writing (summer 2013) the term API (http://dictionary.reference.com/browse/API?s=t) has made its way into the popular lexicon of the English language.  A few years ago, …
Shoutout to Emily Plummer (http://www.experts-exchange.com/members/eplummer26.html) for giving me this article! She did most of it, I just finished it up and posted it for her :)    Introduction In a previous article (http://www.experts-exchang…
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

749 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question