jdinesh has asked for the wisdom of the Perl Monks concerning the following question:

How to convert attribute to element using the XML::PARSER module.
Following sample input and output for xml to xml.
Input:
<open1 type="head1"> This is test. <em type="italic">emp</em> this <i>emp</i> is <em type= +"bold">emp</em> test. </open1>

Output:
<doc> <head1> This is test. <emp><italic>emp</italic></emp> this <italic>emp</italic +> is <emp><bold>emp</bold></emp> test. </head1> </doc>

Regards
JD

Replies are listed 'Best First'.
Re: XML to XML
by davorg (Chancellor) on Dec 30, 2002 at 13:54 UTC
      Where can I find the XML::LibXSLT module to install on Windows.
      Many thanks,
      JD
        Many Thanks,
        I installed following Perl moduls
        XML-LibXML.ppd XML-LibXML-Common.ppd XML-LibXML-Iterator.ppd XML-LibXSLT.ppd XML-XPath.ppd XML-SAX.ppd

        I am receiving the following error message
        E:\xml2xml\xslt>perl libxslt.pl Can't load 'C:/Perl/site/lib/auto/XML/LibXML/Common/Common.dll' for mo +dule XML:: LibXML::Common: load_file:One of the library files needed to run this +applicatio n cannot be found at C:/Perl/lib/DynaLoader.pm line 229. at C:/Perl/site/lib/XML/LibXML.pm line 11 Compilation failed in require at C:/Perl/site/lib/XML/LibXML.pm line 1 +1. BEGIN failed--compilation aborted at C:/Perl/site/lib/XML/LibXML.pm li +ne 11. Compilation failed in require at C:/Perl/site/lib/XML/LibXSLT.pm line +8. BEGIN failed--compilation aborted at C:/Perl/site/lib/XML/LibXSLT.pm l +ine 8. Compilation failed in require at libxslt.pl line 1. BEGIN failed--compilation aborted at libxslt.pl line 1.

        Please suggest. JD
Re: XML to XML
by mirod (Canon) on Dec 30, 2002 at 14:22 UTC

    Or you could use XML::Twig ;--)

    The important method here is insert. Here is the POD for it:

    insert ($gi1, $optional_atts1, $gi2, $optional_atts2,...)

    For each gi in the list inserts an element $gi as the only child of the element. The element gets the optional attributes in $optional_atts. All children of the element are set as children of the new element. The upper level element is returned.

    $p->insert( table => { border=> 1}, 'tr', 'td')
    put $p in a table with a visible border, a single tr and a single td and return the table element:
    <p><table border="1"><tr><td>original content of p</td></tr></table> +</p>

    And the code that does what you want:

    #!/usr/bin/perl -w use strict; use XML::Twig; my $t= XML::Twig->new( twig_handlers => { _all_ => sub { $_->insert( s +ort values %{$_->atts}); $_->del_atts; }, }, ) ->parse( \*DATA) ->print; __DATA__ <open1 type="head1"> This is test. <em type="italic">emp</em> this <i>emp</i> is <em type= +"bold">emp</em> test. </open1>
Re: XML to XML
by gjb (Vicar) on Dec 30, 2002 at 13:57 UTC

    This is a very good job for XSLT which is used to transform XML to XML (or anything else for that matter). Have a look at XML::LibXSLT.

    Hope this helps, -gjb-

Re: XML to XML
by grantm (Parson) on Dec 31, 2002 at 03:00 UTC
Re: XML to XML
by Arien (Pilgrim) on Dec 31, 2002 at 04:19 UTC

    From your question question I assume you haven't used XSLT before, so to help you get started here's an XSLT stylesheet that will do the job to get you started.

    <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- When matching the root node, create a 'doc' element in the result tree and process all the child nodes of the root node. --> <xsl:template match="/"> <doc> <xsl:apply-templates /> </doc> </xsl:template> <!-- Matching an 'open1' element causes the creation of an element named after the value of the type attribute of the 'open1' element in the result tree. Any child nodes of the current node are processed and inserted below the newly created element. --> <xsl:template match="open1"> <xsl:element name="{@type}"> <xsl:apply-templates /> </xsl:element> </xsl:template> <!-- Matching an 'em' element causes the insertion of an 'emp' element with a child element named after the value of the type attribute of the 'em' element in the result tree. Any child nodes of the 'em' element are processed (and inserted below the newly created element). --> <xsl:template match="em"> <emp> <xsl:element name="{@type}"> <xsl:apply-templates /> </xsl:element> </emp> </xsl:template> <!-- Matching an 'i' element causes the insertion of an 'italic' element. Nodes resulting from processing child nodes of the current node will be inserted below this element. --> <xsl:template match="i"> <italic> <xsl:apply-templates /> </italic> </xsl:template> </xsl:stylesheet>

    Of course, this isn't a substitute for reading one or more tutorials or (if you are so inclined) the XSLT spec, but it will give you something to play with in the meantime.

    &mdash Arien

Re: XML to XML
by pg (Canon) on Dec 30, 2002 at 18:31 UTC
    The other thing is that XSLT itself is an executable language, which means it can run on its own, without the help of another language, such as Perl, Java etc.

    Of course, there might be benefits to wrap it, but that's a situation by situation thing.

    I seriously suggest you to first get familiar with both XSLT and XML::XSLT, and then base on your needs to determine whether the wrap is a good idea. Or you might decide to use both on a case by case base.

    For details about XSLT, visit W3C