Perl XML :: Simple与嵌套数组

时间:2016-03-11 08:22:12

标签: arrays xml perl nested

我正在使用带有XML :: Simple的perl来打印XML文件的内容。 然而,XML文件的结构阻止我列出所有条目,因为我找不到循环嵌套数组的正确方法。任何人都可以帮助我并展示如何做到这一点吗?

XML结构如下:

//this is the image displayed when there is no support for canvas
    var defaultImageSrc = "images/charRendered.png";
    //this is the default scale to render the image
    var scale = 4;

    function renderMCSkins(classNameIn, scaleIn, replacementImageIn)
    {
        scale = scaleIn || scale;
        defaultImageSrc = replacementImageIn || defaultImageSrc;

        //we need custom support for IE, because it doesn't support getElementsByClassName
        if (navigator.appName=="Microsoft Internet Explorer") {
            var skinImages = getElementsByClassName(classNameIn, 'img');
        } else {
            var skinImages = document.getElementsByClassName(classNameIn);
        }

        var canvasSupported = supportsCanvas();

        //walk trough the images
        for(var i in skinImages)
        {
            var skin = skinImages[i];

            //if canvas is supported, we render the image to a skin
            if(canvasSupported) {
                if(skin.complete) {
                    renderSkin(skin);
                }
                else {
                    skin.onload = handleSkinLoaded;
                    skin.onerror = handleImageError;
                }
            } else {
                //if it's not supported, we use the default image
                skin.src = defaultImageSrc;
            }
        }
    }

    function handleSkinLoaded() {
        renderSkin(this);
    }

    function handleImageError() {
        //create replacement image
        var replacement = new Image();
        replacement.src = defaultImageSrc;
        //we assign the same classname the image has, for CSS purposes
        replacement.setAttribute('class', this.getAttribute('class'));
        this.parentNode.replaceChild(replacement, this);
    }

    function renderSkin(skinImage) {
        //we create a new canvas element
        var canvas = document.createElement('canvas');
        canvas.width = 64;
        canvas.height = 128;
        //we assign the same classname the image has, for CSS purposes
        canvas.setAttribute('class', skinImage.getAttribute('class'));
        var context = canvas.getContext("2d");
        var s = scale;
        //draw the head
        context.drawImage(skinImage, 8,  8,  8, 8,  4*s,  0*s,  8*s, 8*s);
        //draw the body
        context.drawImage(skinImage, 20, 20, 8, 12, 4*s,  8*s,  8*s, 12*s);
        //draw the left leg
        context.drawImage(skinImage, 4,  20, 4, 12, 4*s,  20*s, 4*s, 12*s);
        //draw the right leg
        context.drawImage(skinImage, 4,  20, 4, 12, 8*s,  20*s, 4*s, 12*s);
        //draw the left arm
        context.drawImage(skinImage, 44, 20, 4, 12, 0*s,  8*s,  4*s, 12*s);
        //draw the right arm
        context.drawImage(skinImage, 52, 20, 4, 12, 12*s, 8*s,  4*s, 12*s);

        //we replace the image with the canvas
        skinImage.parentNode.replaceChild(canvas, skinImage);
    }

    //helper function for IE
    function getElementsByClassName(className, tag, elm){
        var testClass = new RegExp("(^|\\s)" + className + "(\\s|$)");
        var tag = tag || "*";
        var elm = elm || document;
        var elements = (tag == "*" && elm.all)? elm.all : elm.getElementsByTagName(tag);
        var returnElements = [];
        var current;
        var length = elements.length;
        for(var i=0; i<length; i++){
            current = elements[i];
            if(testClass.test(current.className)){
                returnElements.push(current);
            }
        }
        return returnElements;
    }

    //helper function to check canvas support
    function supportsCanvas() {
        canvas_compatible = false;
        try {
                canvas_compatible = !!(document.createElement('canvas').getContext('2d')); // S60
                } catch(e) {
                canvas_compatible = !!(document.createElement('canvas').getContext); // IE
        } 
        return canvas_compatible;
    }

我的程序是这样的:

<header>
 <rows>
  <row>
   <elem>a</elem>
   <elem>b</elem>
   <elem>c</elem>
  </row>
  <row>
   <elem>d</elem>
   <elem>e</elem>
   <elem>f</elem>
  </row>
 </rows>
</header>

我可以使用

打印elem的单独条目
 my $infile = test.xml;
 my $xml = new XML::Simple (KeyAttr=>[]);
 my $main = $xml->XMLin("$infile",SuppressEmpty => '');

并使用

打印第n个元素的所有条目
 print "$main->{rows}->{row}->[0]->{elem}[0]\n";

这会打印

 for (@{$main->{rows}{row}}) {
    print "$_->{elem}[0] \n";
 }

但是如何打印这个:

 a
 d

感谢您的回答。

2 个答案:

答案 0 :(得分:2)

我会从"don't use XML::Simple"开始 - 我非常喜欢XML::Twig作为一个好用且易于使用的替代品。 (XML::LibXML也很好,但有一点学习曲线):

#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;

my $xml = XML::Twig -> parsefile ( $infile );

foreach my $row ( $xml -> get_xpath('//row') ) {
   print join ( ";", map { $_ -> text } $row -> children('elem')),"\n";
}

打印:

a;b;c
d;e;f

(为了清晰起见,展开循环:

foreach my $row ( $xml -> get_xpath('//row') ) {
   foreach my $elem ( $row -> children ( 'elem' ) ) { 
      print $elem -> text, ";";
   }
   print "\n";
}

答案 1 :(得分:0)

log.info(reqq)