# $Id: XmlElment.pm,v 1.1 2004/11/11 19:49:31 jkremer Exp $
# Copyright 2004 Sun Microsystems, Inc., All Rights Reserved.
# Sun Proprietary/Confidential: For Internal Use Only
package Catalog::XmlElement;

use XML::LibXML;
use Data::Dumper;
use strict;

sub newFromFile {
  my ($class, $file) = @_;

  if (open(O, $file)) {
     my @l = <O>; close(O);
     return Catalog::XmlElement->newFromString("@l");
  } else {
	 my $this = { error => "opening $file: $! \n"};
	 bless $this, 'Catalog::XmlElement';
	 return $this;
  }
}

sub newFromString {
  my ($class, $doc) = @_;

  my $this = {};
  bless $this, 'Catalog::XmlElement';

  my $parser = XML::LibXML->new();
  my $dom  = $parser->parse_string($string);
  if (!$dom){
	 $this->{error}("Error parsing XML document element.");
	 return $this;
  }

  $this->{element} = $dom->getDocumentElement();
}

sub new {
  my ($class, $element) = @_;
  my $this = { element => $element };
  bless $this, 'Catalog::XmlElement';
  return $this;
}

#Get the name of the XML element
sub getName() {
  my ($this) = @_;
  my $element = $this->{element};
  if ($element){
	 return $element->getName();
  }
  return undef;
}

sub getStringValue {
  my ($this) = @_;
  my $element = $this->{element};
  if ($element){
	 return $element->textContent();
  }
  return undef;
}

sub getAttribute {
  my ($this, $attName) = @_;
  my $element = $this->{element};
  if ($element){
	 return $element->getAttribute($attName);
  }
  return undef;
}

sub getChildren {
  my ($this, $elemNameFilter) = @_;
  my $node = $this->{element};
  my $list = ();
  foreach my $el ($node->getChildNodes()){
	 if ($el->getType() == &XML::LibXML::ELEMENT_NODE() ){
		if (!$elemNameFilter){
		  push($list, new Catalog::XmlElement($el));
		}
		elsif ($el->getName eq $elemNameFilter){
		  push($list, new Catalog::XmlElement($el));
		}
	 }
  }
  return $list;
}

sub getElement {
  my ($this, $elemName, $keyName, $keyValue) = @_;
  my $node = $this->{element};
  foreach my $el ($node->getChildNodes()){
	 if ($el->getType() == &XML::LibXML::ELEMENT_NODE() ){
		if ($el->getName() == $elemName){
		  if ($keyName){
			 if ($el->getAttribute($keyName) eq $keyValue){
				return new Catalog::XmlElement($el);
			 }
		  }
		  else {
			 return new Catalog::XmlElement($el);
		  }
		}
	 }
  }
  return undef;
}


sub getKeyedElements {
  my ($this, $elemName, $keyName) = @_;
  my $values = {};
  my $node = $this->{element};
  foreach my $el ($node->getChildNodes()){
	 if ($el->getType() == &XML::LibXML::ELEMENT_NODE() ){
		if ($el->getName() == $elemName){
		  $values->{$el->getAttribute($keyName)} = new Catalog::XmlElement($el);
		}
	 }
  }
  return $values;
}

# <NODE><VALUE ID="a">1</VALUE><VALUE ID="b">2</VALUE></NODE>
sub getKeyedValues {
  my ($this, $elemName, $keyName) = @_;
  my $values = {};
  my $node = $this->{element};
  foreach my $el ($node->getChildNodes()){
	 if ($el->getType() == &XML::LibXML::ELEMENT_NODE() ){
		if ($el->getName() == $elemName){
		  $values->{$el->getAttribute($keyName)} = $el->textContent();
		}
	 }
  }
  return $values;
}

# return hash of element with values.
# <NODE><name1>value1</name1></name2>value2</name2></NODE>
sub getNamedValues {
  my ($this) = @_;
  my $values = {};
  my $node = $this->{element};
  foreach my $el ($node->getChildNodes()){
	 if ($el->getType() == &XML::LibXML::ELEMENT_NODE() ){
		$values->{$el->getName()} = $el->textContent();
	 }
  }
  return $values;
}
