Puppet provider - xml parsing - help needed

90 views
Skip to first unread message

Martin Alfke

unread,
Feb 25, 2015, 12:18:02 PM2/25/15
to puppet-dev
Hi,

I am stuck at a puppet provider where I need to read data from xml.

Data which needs to get parsed:

<AR>
<AR_ID><![CDATA[8]]></AR_ID>
<IP><![CDATA[172.16.100.208]]></IP>
<MAC><![CDATA[02:00:ac:10:64:d0]]></MAC>
<SIZE><![CDATA[1]]></SIZE>
<TYPE><![CDATA[IP4]]></TYPE>
<USED_LEASES>0</USED_LEASES>
<LEASES/>
</AR>
<AR>
<AR_ID><![CDATA[9]]></AR_ID>
<IP><![CDATA[172.16.100.209]]></IP>
<MAC><![CDATA[02:00:ac:10:64:d1]]></MAC>
<SIZE><![CDATA[1]]></SIZE>
<TYPE><![CDATA[IP4]]></TYPE>
<USED_LEASES>0</USED_LEASES>
<LEASES/>
</AR>


Expected result:

:addressrange =>
{ ‘1' =>
{ ‘ip' => ‘172.16.100.208’, ‘mac' => ’02:00:ac:10:64:d0’ },
‘2' =>
{ ‘ip' => ‘172.16.100.209’, ‘mac' => ’02:00:ac:10:64:d1’ }
}


Actual code (Note: I was never good at coding an will never be):

vnets.collect do |vnet|
new(
:addressrange => Hash[vnet.xpath('./AR_POOL/AR/AR_ID').collect { |ar| [ar.text, ar.xpath('..').collect { |singlear| singlear.xpath('./*').collect { |arvalue| {arvalue.name, arvalue.text} } } ] } ]
)
end


But this code return:
:addressrange=>
{"9"=>
[[{"AR_ID"=>"9"},
{"IP"=>"172.16.100.209"},
{"MAC"=>"02:00:ac:10:64:d1"},
{"SIZE"=>"1"},
{"TYPE"=>"IP4"}]],
"8"=>
[[{"AR_ID"=>"8"},
{"IP"=>"172.16.100.208"},
{"MAC"=>"02:00:ac:10:64:d0"},
{"SIZE"=>"1"},
{"TYPE"=>"IP4"}]],

What would be proper code to build the hash as expected?

Thanks,

Martin

Henrik Lindberg

unread,
Feb 25, 2015, 1:43:42 PM2/25/15
to puppe...@googlegroups.com
> What would be proper code to build the hash as expected?
>

That is not easy. Is the structure static and only varying where the
actual data is? If so, you could hard code a solution. If you expect
there to be variability in the tags/layout you should consider using an
XML parser and get the data from it.

To do this with regular expressions you need to match the part:

<IP><![CDATA[172.16.100.209]]></IP>
<MAC><![CDATA[02:00:ac:10:64:d1]]></MAC>

with something like this (untested):

/<IP><!\[CDATA|[(.*)\]]></IP>.*<MAC><!\[CDATA\[(.*)\]]></MAC>/

Then apply that to iterate over matches - you need to do matching that
accepts newlines as a match for . etc.

Play with it in Rubular (online ruby regexp tester) until you get it right.

- henrik
--

Visit my Blog "Puppet on the Edge"
http://puppet-on-the-edge.blogspot.se/

Thomas Hallgren

unread,
Feb 25, 2015, 2:18:53 PM2/25/15
to puppe...@googlegroups.com
I would take a look at nokogiri. It's an XML/HTML parser for Ruby. Some
helpful hints here:
http://stackoverflow.com/questions/11198239/parsing-xml-with-ruby

- thomas

Martin Alfke

unread,
Feb 25, 2015, 2:36:18 PM2/25/15
to puppe...@googlegroups.com
Many thanks for the feedback.
Structure and Data can vary (depending on functionality - in this case ipv4 vs. ipv6).

I was only doing one thing wrong in my code (one level of indirection too much)
The following solution works:

:addressrange => Hash[vnet.xpath('./AR_POOL/AR/AR_ID').collect { |ar| [ar.text, Hash[ar.xpath('../*').collect { |singlear| [singlear.name.downcase, singlear.text.downcase] } ] ] } ]

I know receive all data as nested hash in the address range attribute.

Best,

Martin
> --
> You received this message because you are subscribed to the Google Groups "Puppet Developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to puppet-dev+...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-dev/54EE2012.8020206%40puppetlabs.com.
> For more options, visit https://groups.google.com/d/optout.

Raphaël Pinson

unread,
Feb 25, 2015, 6:45:46 PM2/25/15
to puppe...@googlegroups.com
Hi Martin,


Have you considered using an Augeas provider here, using the Xml lens?


Cheers,

Raphaël

Martin Alfke

unread,
Feb 26, 2015, 3:02:24 AM2/26/15
to puppe...@googlegroups.com
Hi Raphael,

can the Augeas provider “translate” from xml into Puppet DSL and vice versa?
That would be nice.

Best,
Martin
> --
> You received this message because you are subscribed to the Google Groups "Puppet Developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to puppet-dev+...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-dev/81914d3c-aeab-4991-80ca-4a4544e2f3cb%40googlegroups.com.

Raphaël Pinson

unread,
Mar 9, 2015, 8:39:46 AM3/9/15
to puppe...@googlegroups.com
Hi Martin,


What do you mean by "translating to Puppet DSL"? Do you have an example of what you want to achieve?



Raphaël
Reply all
Reply to author
Forward
0 new messages