سؤال

Goal: generate the Perl data structure needed to populate and write XML output, using an existing XSD schema.

What I've done: I've installed XML::Compile, found a tutorial on how to use it, and read through a modified example here. I've processed my XSD file using CAM Template Editor to ensure CAM can generate an example XML file from the template, which it can, and I've compared the XML output to the XSD to ensure the two relate the way I think they should. They do.

Next, I've simply pointed XML::Compile::Schema to the XSD file, then asked that the template string be created, asking template() to start at the root element as specified in the XSD.

What's Wrong: "error: cannot find element or attribute '[root_element_name]'

My XSD does differ from those I've seen in the examples I've found. Here's what I have:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd"
    elementFormDefault="qualified"
    xmlns="http://tempuri.org/XMLSchema.xsd"
    xmlns:mstns="http://tempuri.org/XMLSchema.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"

<xs:annotation></xs:annotation>

<!-- Include XML Schema containing type definitions and data validation -->
  <xs:include id="DataDefinitions" schemaLocation="DataDefinitions_XMLSchema.xsd"></xs:include>

  <!-- Root element -->
  <xs:element name="Metrics" type="metrics"></xs:element>

  <xs:complexType name ="metrics">
    <xs:sequence minOccurs ="1" maxOccurs ="1">
      <xs:element name = ...></xs:element>
      .
      .
      <xs:element name = ....></xs:element>
    </xs:sequence>
  </xs:complexType>

  [other complexType definitions used above to type some of the elements in the complexType 'metrics']

</xs:schema>

Several of the elements above have types that are then defined below the section I've shown, and that is the essence of the XSD. I've left out much of that detail here clearly but I don't think ('hope') it's pertinent to the problem.

The Perl is pretty straightforward, even if wrong:

use warnings;
use strict;
use XML::LibXML;
use XML::Compile;

my $xsd = 'C:\schema.xsd';
my $schema = XML::Compile::Schema=>new($xsd);
my $xml_template = $schema->template('PERL', 'Metrics');

This fails with the error mentioned above:

error: cannot find element or attribute named 'Metrics'

Thinking I probably don't understand when namespace qualification is needed and when it isn't, I qualified Metrics and called

my $xml_template = $schema->template('PERL', 'mstns:Metrics');

and that fails the same way.

Other examples I've seen of defining the root element are done like so:

<element name = "Metrics">
  <complexType>
    <sequence>
      [etc]
    </sequence>
  </complexType>
</element>

rather than the way this one is done, and I wonder if the problem is some change in allowed style that XML::Compile doesn't recognize. I simply don't know how to determine why template() doesn't find the element I've specified.

Suggestions?

هل كانت مفيدة؟

المحلول

Specify the targetNamespace as the type in your template call in curly braces... like this:

use warnings;
use strict;
use XML::LibXML;
use XML::Compile;

my $xsd = 'C:\schema.xsd';
my $schema = XML::Compile::Schema=>new($xsd);
my $xml_template = $schema->template('PERL', '{http://tempuri.org/XMLSchema.xsd}Metrics');
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top