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

Hi guys,
I want to extract some elements and attributes from a large XML file. My code below works fine with elements, but it just print one attribute which is snpClass and does not print the other two attributes which they are rsId and snpType. Any advice or tips to solve this problem. Thanks in advance
----------------------------------------

use XML::Twig; my $outfile = 'extra.snp'; open my $out,'>',$outfile or die "Could not open file '$outfile' $!"; my $file = shift @ARGV; #the file to parse my $twig = XML::Twig->new ( twig_handlers => { 'Rs' => \&rsId, 'Rs' => \&snpType, 'Rs' => \&snpClass, 'Rs/Sequence/Observed' => \&Observed, 'Rs/Sequence/Seq3' => \&Seq3, 'Rs/Sequence/Seq5' => \&Seq5, } ); $twig -> parsefile( "$file"); sub rsId { my ($twig, $elt) = @_; print $out $elt->att('rsId'), "\n"; } sub snpType { my ($twig, $elt) = @_; print $out $elt->att('snpType'), "\n"; } sub snpClass { my ($twig, $elt) = @_; print $out $elt->att('snpClass'), "\n"; } sub Observed { my ($twig, $elt) = @_; print $out $elt->text, "\t"; } sub Seq5 { my ($twig, $elt) = @_; print $out substr($elt->text, -30,30), "\t"; } sub Seq3 { my ($twig, $elt) = @_; print $out substr($elt->text, 0,30), "\t"; }

Here is the part of my file
-----------------------------------------

<?xml version="1.0" encoding="UTF-8"?> <ExchangeSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml +ns="http:/ /www.ncbi.nlm.nih.gov/SNP/docsum" xsi:schemaLocation="http://www.ncbi. +nlm.nih.go v/SNP/docsum ftp://ftp.ncbi.nlm.nih.gov/snp/specs/docsum_3.4.xsd" spec +Version="3 .4" dbSnpBuild="144" generated="2015-05-26 09:54"> <SourceDatabase taxId="9606" organism="human" gpipeOrgAbbr="hs"/> <Rs rsId="3894" snpClass="snp" snpType="notwithdrawn" molType="gen +omic" genotype="true" bitField="050028000005130500030100" taxId="9606 +"> <Het type="est" value="0.05" stdError="0.1547"/> <Validation byCluster="true" byOtherPop="true" byHapMap="true" + by1000G=" true"> <otherPopBatchId>7179</otherPopBatchId> </Validation> <Create build="36" date="2000-09-19 17:02"/> <Update build="144" date="2015-05-07 10:52"/> <Sequence exemplarSs="491581208" ancestralAllele="C,C"> <Seq5>ATAAGCAAATAACTGAAGTTTAATCAGTCTCCTCCCAGCAAGTGATATGCAA +CTGAGATTCC TTATGACACATCTGAACACTAGTGGATTTGCTTTGTAGTAGGAACAAGGTACATTCGCGGGATAAATGTG +GCCAAGTTTT ATCTGCTGCCAGGGCTTTCAAATAGGTTGACCTGACAATGGGTCACCTCTGGGACTGA</Seq5> <Observed>C/T</Observed> <Seq3>AATTAGGAAGAGCTGGTACCTAAAATGAAAGATGCCCTTAAATTTCAGATTC +ACAATTTTTT TTTCTTAGTATAAGCATGTCCCATGTAATATCTGGGATATACTCATACCTTTAAAAATGTGCTCATTGTT +TATCTGAAAT TCACATTTTAACAGGGAACCATTGTTTTGTTATTGTTTATTGTTTTGTTTCTAAATAA</Seq3> </Sequence>

Replies are listed 'Best First'.
Re: print multi XML attributes using twig xml
by toolic (Bishop) on Sep 10, 2015 at 14:59 UTC
    The problem is that a Perl hash key can only have one value, but you assigned the Rs key to 3 values. Here is one way to get what you want:
    use warnings; use strict; use XML::Twig; my $xml = <<XML; <foo> <Rs rsId="3894" snpClass="snp" snpType="notwithdrawn" molType="gen +omic" genotype="true" bitField="050028000005130500030100" taxId="9606 +"/> </foo> XML my $twig = XML::Twig->new ( twig_handlers => { 'Rs' => \&rs, } ); $twig->parse($xml); sub rs { my ($twig, $elt) = @_; print $elt->att('rsId'), "\n"; print $elt->att('snpType'), "\n"; print $elt->att('snpClass'), "\n"; } __END__ 3894 notwithdrawn snp

      Thanks a lot, the problem is solved by your suggestion