Re: XML::Simple in Xerces (was Re: Xerces-perl for Win32)

Brian Faull <[email protected]>
Newsgroups gmane.text.xml.xerces-p.devel
Organization The MITRE Corporation
Message-ID <[email protected]>
"Jason E. Stewart" wrote:

> > Wow, thanks!
> 
> Welcome. New users always inspire me to add features to Xerces.

Glad I could help! :)

> looks like you hit the 'send' key before the 'attach' key, we didn't
> get anything.

Drat... I do that far more often than I'd like to admit... I'm typing this
*after* I attached the file this time. Sorry for the spam.

> > p.s. sorry that the subject in this thread has strayed so far from the
> > original 'subject'...
> 
> time for a subject change, I think...

Good subject! :)
-brian



"Jason E. Stewart" wrote:
> 
> Brian Faull <[email protected]> writes:
> 
> > Wow, thanks!
> 
> Welcome. New users always inspire me to add features to Xerces.
> 
> > Attached, if anyone is interested, is a modification of node2hash that
> > creates a data structure that is identical to that which XML::Simple
> > creates in XMLin(). It's not pretty, but neither is the data structure
> > used by XML::Simple. :)
> 
> looks like you hit the 'send' key before the 'attach' key, we didn't
> get anything.
> 
> > I've written one the other way, too, but it's still flaky; I'll post both
> > again when I've cleaned them up.
> 
> Ok, sounds good.
> 
> > Thanks again,
> > -brian
> 
> you're welcome.
> 
> > p.s. sorry that the subject in this thread has strayed so far from the
> > original 'subject'...
> 
> time for a subject change, I think...

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
node2hash.pl (application/x-perl, 2.6 KB)
# Construct the ridiculous data structure used by XML::Simple
# Each node (except toplevel!) is an arrayref.
# For text nodes, the hashref in the first element of the arrayref includes a key
#   'content' whose value is an arrayref of all of the text nodes within parent node.
# For attributes of a node, the first element of the arrayref includes a key having
#   the same name as the attribute name, and the value is an arrayref. If there exists
#   one or more child nodes with the same name as an attribute name, the first element
#   of the arrayref is the value of the attribute, and the remaining elements are
#   hashrefs containing one key 'content' whose value is the enclosed text.
# For children of the node, there is a key that points to an arrayref, as above.
# If there is more than one node of the same type, these are represented as individual
#   hashrefs within the enclosing arrayref.
# This is perhaps an oversimplification. Further information in XML::Simple

sub node2hash {
  my $node = shift;
  my $return = [{}];

  # build a hashref that represents the attributes of this element
  my $nodename = $node->getNodeName();
  if ($node->hasAttributes()) {
    my %attrs = $node->getAttributes();
    foreach my $attr (keys %attrs) {
      $return->[0]->{$attr} = $attrs{$attr};
    }
  }

  # recursively create structures for child nodes...
  # sorry, this gets kinda ugly...
  if ($node->hasChildNodes()) {
    my @text = ();
    foreach my $child ($node->getChildNodes()) {
      my $childname = $child->getNodeName();
      if ($child->isa('XML::Xerces::DOMElement')) {
        if (exists $return->[0]->{$childname}) {
          if (UNIVERSAL::isa($return->[0]->{$childname}, 'ARRAY')) {
            push @{$return->[0]->{$childname}}, node2hash($child)->[0];
          }
          else {
            $return->[0]->{$childname} = [$return->[0]->{$childname}, node2hash($child)->[0]];
          }
        }
        else { $return->[0]->{$childname} = node2hash($child); }
      }
      elsif ($child->isa('XML::Xerces::DOMText')) {
        my $val = $child->getNodeValue();
        push @text, $val
          if $val =~ m/\S+/;
      }
    }

    # Add text nodes as key 'content'
    if (exists $return->[0]->{'content'}) {
      if (UNIVERSAL::isa($return->[0]->{'content'}, 'ARRAY')) {
        unshift @{$return->[0]->{'content'}}, @text;
      }
      else { warn "content element should be array"; }
    }
    else {
      if (scalar @text == 1) { $return->[0]->{'content'} = $text[0]; }
      if (scalar @text >  1) { $return->[0]->{'content'} = \@text; }
    }
  }
  return $return;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.