Extracting data from an XML document that uses namespaces

后端 未结 2 739
独厮守ぢ
独厮守ぢ 2020-12-09 21:14

I have some XML files where I want to use some information from them. I have written a code that reads those files and then looks for some conditions.

The problem is

相关标签:
2条回答
  • 2020-12-09 21:35

    Perl has so many excellent XML tools - thanks to all the module developers and libxml2, XML almost seems easy. One of those tools is XML::Dataset - a convenience "scaffolding" module that builds on XML::LibXML and uses a "profile" markup language to grab data from XML sources (NB: The profile mark-up is sensitive to whitespace and line endings).

    e.g.:

    use XML::Dataset;
    use DDP;
    
    my $xml = "Squish.xml" ; 
    open my $fh, "<", $xml or die "aiiieee!";
    my $test_data = do { local $/; <$fh> };
    
    # describe the data using XML::Dataset simplified markup:
    my $data_profile
        = q(
              SquishReport
                test
                  test
                     name = dataset:name);
    
    # parse it with XML::Dataset profile
    my $parsed_data = parse_using_profile($test_data, $data_profile);
    
    # view the element with Data::Printer
    foreach my $element ( $parsed_data->{name}){
         p $element ;
    };
    

    Squish.xml:

    <SquishReport version="2.1" xmlns="http://www.froglogic.com/XML2">
       <test name="TEST">
          <prolog time="2015-10-01T03:45:22+02:00"/>
          <test name="tst_start_app">
              <prolog time="2015-02-01T03:45:23+02:00"/>
              <message line="38" type="LOG" file="C:\squish\test\sources.py" time="2015-02-01T03:45:23+02:00">
                  <description>
                    <![CDATA[>>  >>  >> start: init (global) - testcase C:\squish\test\tst_start_app]]></description>
              </message>
           </test>
       </test>
    </SquishReport>
    

    Output:

    \ [
        [0] {
            name   "tst_start_app"
        }
    ]
    
    0 讨论(0)
  • 2020-12-09 21:43

    The root node of that document is an element which has name SquishReport in the http://www.froglogic.com/XML2 namespace. Concisely, we can say the root node is a

    {http://www.froglogic.com/XML2}SquishReport
    


    When one uses SquishReport (as opposed to prefix:SquishReport) in an XPath, that tries to match an element which has name SquishReport in the null namespace. Concisely, we can say it attempts to match a

    {}SquishReport
    


    To specify the namespace, one uses prefixes defined in a context, as follows:

    use strict;
    use warnings;
    use feature qw( say );
    
    use XML::LibXML               qw( );
    use XML::LibXML::XPathContext qw( );
    
    my $xpc = XML::LibXML::XPathContext->new();
    $xpc->registerNs(sr => 'http://www.froglogic.com/XML2');
    
    my $doc = XML::LibXML->load_xml( location => 'test.xml' );
    for my $entry ($xpc->findnodes('/sr:SquishReport/sr:test/sr:test', $doc)) {
        my $key = $entry->findvalue('@name');
        say $key;
    }
    


    Note: The prefix used in the XPath have no relation to the prefixes used in the XML document (if any). You are expected to know the namespace in which resides the elements for which you are searching, but not the prefixes used by a given document.

    0 讨论(0)
提交回复
热议问题