Visit Our UNIX and Linux User Community


Perl XML, find matching condition and grep lines and put the lines somewhere else


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Perl XML, find matching condition and grep lines and put the lines somewhere else
# 1  
Old 11-02-2010
Power Perl XML, find matching condition and grep lines and put the lines somewhere else

Hi,

my xml files looks something like this
Code:
<Instance Name="New York">
      <Description></Description>
      <Instance Name="A">
        <Description></Description>
        <PropertyValue Key="false" Name="Building A" />
      </Instance>
      <Instance Name="B">
        <Description></Description>
        <PropertyValue Key="false" Name="Building B" />
      </Instance>
      <PropertyValue Key="false" Name="random" />
      <PropertyValue Key="false" Name="blabla" />
      <PropertyValue Key="false" Name="blabla2" />
    </Instance>

I need to grep all the lines between </Instance> and </Instance> {the 3 proeprty values, there cna be 4 or more, and place them on top between </Description> and <Instance, so it becomes like this

<Instance Name="New York">
<Description></Description>
<PropertyValue Key="false" Name="random" />
<PropertyValue Key="false" Name="blabla" />
<PropertyValue Key="false" Name="blabla2" />

<Instance Name="A">
<Description></Description>
<PropertyValue Key="false" Name="Building A" />
</Instance>
<Instance Name="B">
<Description></Description>
<PropertyValue Key="false" Name="Building B" />
</Instance>
</Instance>

[/CODE]

For the notes, There can be more than 1 parent in file. The Instance name will also be different than New York, but what I need to highlight is the string matching condition. In short, a complete file may look like this

Code:
<Instance Name="New York">
      <Description></Description>
      <Instance Name="A">
        <Description></Description>
        <PropertyValue Key="false" Name="Building A" />
      </Instance>
      <Instance Name="B">
        <Description></Description>
        <PropertyValue Key="false" Name="Building B" />
      </Instance>
      <PropertyValue Key="false" Name="random" />
      <PropertyValue Key="false" Name="blabla" />
      <PropertyValue Key="false" Name="blabla2" />
    </Instance>
<Instance Name="Mumbai">
       <Description></Description>
      <Instance Name="C">
         <Description></Description>
         <PropertyValue Key="false" Name="Building C" />
       </Instance>
       <Instance Name="D">
         <Description></Description>
         <PropertyValue Key="false" Name="Building D" />
      </Instance>
      <PropertyValue Key="false" Name="absolute" />
      <PropertyValue Key="false" Name="perl" />
      <PropertyValue Key="false" Name="xml" />
    </Instance>

In which case, the result needs to be like this


Code:
<Instance Name="New York">
      <Description></Description>
      <PropertyValue Key="false" Name="random" />
      <PropertyValue Key="false" Name="blabla" />
      <PropertyValue Key="false" Name="blabla2" />
       <Instance Name="A">
        <Description></Description>
        <PropertyValue Key="false" Name="Building A" />
      </Instance>
      <Instance Name="B">
        <Description></Description>
        <PropertyValue Key="false" Name="Building B" />
      </Instance>
    </Instance>
<Instance Name="Mumbai">
       <Description></Description>
      <PropertyValue Key="false" Name="absolute" />
      <PropertyValue Key="false" Name="perl" />
      <PropertyValue Key="false" Name="xml" />
       <Instance Name="C">
         <Description></Description>
         <PropertyValue Key="false" Name="Building C" />
       </Instance>
       <Instance Name="D">
         <Description></Description>
         <PropertyValue Key="false" Name="Building D" />
       </Instance>
    </Instance>

I wonder if this is possible, please help. Thank you very much.Really appreciate it.
# 2  
Old 11-03-2010
Try this
Code:
#!/usr/bin/perl

use XML::LibXSLT;
use XML::LibXML;

my $parser = XML::LibXML->new();
my $xslt = XML::LibXSLT->new();

my $source = $parser->parse_file('example.xml');
my $style_doc = $parser->parse_file('example.xsl');

my $stylesheet = $xslt->parse_stylesheet($style_doc);

my $results = $stylesheet->transform($source);

print $stylesheet->output_string($results);

For this to work you input document (example.xml) needs to be well-formed. Thus I have added a root element called "Instances".
Code:
<Instances>
   <Instance Name="New York">
      <Description></Description>
      <Instance Name="A">
         <Description></Description>
         <PropertyValue Key="false" Name="Building A" />
      </Instance>
      <Instance Name="B">
         <Description></Description>
         <PropertyValue Key="false" Name="Building B" />
      </Instance>
      <PropertyValue Key="false" Name="random" />
      <PropertyValue Key="false" Name="blabla" />
      <PropertyValue Key="false" Name="blabla2" />
   </Instance>
   <Instance Name="Mumbai">
      <Description></Description>
      <Instance Name="C">
         <Description></Description>
         <PropertyValue Key="false" Name="Building C" />
      </Instance>
      <Instance Name="D">
         <Description></Description>
         <PropertyValue Key="false" Name="Building D" />
      </Instance>
      <PropertyValue Key="false" Name="absolute" />
      <PropertyValue Key="false" Name="perl" />
      <PropertyValue Key="false" Name="xml" />
   </Instance>
</Instances>

Here is the stylesheet (example.xsl). This can handle any number of PropertyValue elements as requested.
Code:
<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

   <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

   <xsl:strip-space elements="*" />

   <xsl:template match="/Instances/Instance">
       <xsl:element name='{name()}'>
           <xsl:copy-of select="Description"/>
           <xsl:for-each select="child::PropertyValue">
              <xsl:copy-of select="." />
           </xsl:for-each>
           <xsl:for-each select="child::Instance">
              <xsl:copy-of select="." />
           </xsl:for-each>
       </xsl:element><xsl:text>
</xsl:text>
   </xsl:template>

</xsl:stylesheet>

and here is the result document
Code:
<Instance>
  <Description/>
  <PropertyValue Key="false" Name="random"/>
  <PropertyValue Key="false" Name="blabla"/>
  <PropertyValue Key="false" Name="blabla2"/>
  <Instance Name="A">
    <Description/>
    <PropertyValue Key="false" Name="Building A"/>
  </Instance>
  <Instance Name="B">
    <Description/>
    <PropertyValue Key="false" Name="Building B"/>
  </Instance>
</Instance>
<Instance>
  <Description/>
  <PropertyValue Key="false" Name="absolute"/>
  <PropertyValue Key="false" Name="perl"/>
  <PropertyValue Key="false" Name="xml"/>
  <Instance Name="C">
    <Description/>
    <PropertyValue Key="false" Name="Building C"/>
  </Instance>
  <Instance Name="D">
    <Description/>
    <PropertyValue Key="false" Name="Building D"/>
  </Instance>
</Instance>

# 3  
Old 11-03-2010
had problem with perl when executing it. I installed the necessary perl modules but it failed to run. Is there an alternative for this?
# 4  
Old 11-03-2010
Quote:
had problem with perl when executing it. I installed the necessary perl modules but it failed to run. Is there an alternative for this?
That is strange. What errors were you getting?

Sure, you can use any XSLT processor.

For example, from a GNU/Linux command line:
Quote:
$ xsltproc example.xsl example.xml
# 5  
Old 11-03-2010
Perl crashed basically. I wonder if there are any other methods to do this beside using that XSLT.

Previous Thread | Next Thread
Test Your Knowledge in Computers #110
Difficulty: Easy
As of 2014, Apple's macOS was the largest Unix installed base globally.
True or False?

10 More Discussions You Might Find Interesting

1. UNIX for Dummies Questions & Answers

Grep certain lines with condition

file input aaaa,52C aaaa,50C bbbb,50C bbbb,58C aaaa,52C bbbb,50C aaaa,30C bbbb,58C cccc,60C i want to print uniq lines with its max value of column2 expected output aaaa,52C bbbb,58C cccc,60C tks (4 Replies)
Discussion started by: radius
4 Replies

2. UNIX for Dummies Questions & Answers

Grep to find lines matching given patern in a file

When I try with patern matching in a file with below code works cat scj_drive_commands | egrep '/app/oracle/build_lib/pkg32|/app/oracle/build_lib/pkg33' But when I have code with patern searching using of below does not work ! cat scj_drive_commands | egrep... (3 Replies)
Discussion started by: Siva SQL
3 Replies

3. Shell Programming and Scripting

Grep the non-matching lines

Hi, I need to make a script to extract the number that are not in a file. Example: I have file-A that has 100000 (70000-799999) numbers. And a file-B with number that already are in the system. Now I need to know/get the numbers that are not in system. I was thinking something like this:... (5 Replies)
Discussion started by: AK47
5 Replies

4. Shell Programming and Scripting

Perl Regex matching multiple lines

I need a way to extract data from X 4T Solution 21 OCT 2011 37 .00 to account 12345678 User1 user2 X 4T Solution Solution Unlimited 11 Sep 2009 248 .00 to account 87654321 user3 user4 I need it to extract 'X' '37.00' and account number 12345678. I have extracted above stuff... (3 Replies)
Discussion started by: chakrapani
3 Replies

5. Shell Programming and Scripting

Remove lines from XML based on condition

Hi, I need to remove some lines from an XML file is the value within a tag is empty. Imagine this scenario, <acd><acdID>2</acdID><logon></logon></acd> <acd><acdID></acdID><logon></logon></acd> <acd><acdID></acdID><logon></logon></acd> <acd><acdID></acdID><logon></logon></acd> I... (3 Replies)
Discussion started by: giles.cardew
3 Replies

6. Shell Programming and Scripting

perl or awk remove empty lines when condition

Hi Everyone, # cat 1 a b b cc 1 2 3 3 3 4 55 5 a b (2 Replies)
Discussion started by: jimmy_y
2 Replies

7. Shell Programming and Scripting

use awk pick value from lines as condition for grep

Hi Folks! I have a file like this 000000006 dist:0.0 FILE ./MintRoute/MultiHopWMEWMA.nc LINE:305:1 NODE_KIND:131 nVARs:4 NUM_NODE:66 TBID:733 TEID:758 000000000 dist:0.0 FILE ./Route/MultiHopLEPSM.nc LINE:266:1 NODE_KIND:131 nVARs:4 NUM_NODE:66 TBID:601 TEID:626 000000001 ... (2 Replies)
Discussion started by: jackoverflow
2 Replies

8. Shell Programming and Scripting

AIX equivalent to GNU grep's -B and -A [print lines after or before matching lines]

Hi folks I am not allowed to install GNU grep on AIX. Here my code excerpt: grep_fatal () { /usr/sfw/bin/gegrep -B4 -A2 "FATAL|QUEUE|SIGHUP" } Howto the same on AIX based machine? from manual GNU grep ‘--after-context=num’ Print num lines of trailing context after... (4 Replies)
Discussion started by: slashdotweenie
4 Replies

9. Shell Programming and Scripting

swapping lines that match a condition using sed, perl or the like

I'm a bit new to regex and sed/perl stuff, so I would like to ask for some advice. I have tried several variations of scripts I've found on the net, but can't seem to get them to work out just right. I have a file with the following information... # Host 1 host 45583 { filename... (4 Replies)
Discussion started by: TheBigAmbulance
4 Replies

10. UNIX for Dummies Questions & Answers

Find matching lines between 2 files

How do I find matching lines between two files? (5 Replies)
Discussion started by: jojojmac5
5 Replies

Featured Tech Videos