DTDReader(3)

πŸ“¦
version 0.04 Β· 2 versions
, in fedora 43

πŸ’– DTDReader(3) πŸ’–

User Contributed Perl Documentation β€” yes bestie, this is a real manual page and it's lowkey iconic.


✨ NAME ✨

XML::Simple::DTDReader β€” reading simple XML files based on their DTDs. It's giving "XML::Simple but the DTD is the main character." πŸ‘‘


🌸 SYNOPSIS 🌸

  use XML::Simple::DTDReader;

  my $ref = XMLin("data.xml");

Or if you wanna be all object oriented about it (periodt):

  require XML::Simple::DTDReader;

  my $xsd = XML::Simple::DTDReader->new;
  my $ref = $xsd->XMLin("data.xml");

πŸ¦‹ DESCRIPTION πŸ¦‹

XML::Simple::DTDReader is aiming to be a drop-in replacement for XML::Simple, but with a glow-up: several aspects of the module get controlled by the XML's DTD instead. Specifically, array folding and array forcing are inferred from the DTD. no cap.

Right now, only XMLin is supported; support for XMLout is planned for later releases. (soon bestie, we're manifesting it πŸ™)

πŸ’… XMLin()

Parses XML formatted data and hands you back a reference to a data structure holding all that same info in a way easier to actually use. (Skip down to "EXAMPLES" for sample code.) The XML must have a valid <!DOCTYPE> element. Non-negotiable, sorry.

XMLin() accepts an optional XML specifier, which can be one of these lil guys:

  • A filename β€” If the filename contains no directory components, XMLin() will look for the file in the current directory. Heads up: the filename '-' can be used to parse from STDIN. eg:
    $ref = XMLin('/etc/params.xml');
  • undef β€” If there's no XML specifier at all, XMLin() will check the script directory for a file with the same name as the script but with the extension .xml. eg:
    $ref = XMLin();
  • A string of XML β€” A string containing XML (recognized by the presence of < and > characters) gets parsed directly. eg:
    $ref = XMLin('<opt username="bob" password="flurp" />');
  • An IO::Handle object β€” An IO::HAndle object will be read to EOF and its contents parsed. eg:
    $fh = new IO::File('/etc/params.xml');
    $ref = XMLin($fh);

πŸŽ€ OPTIONS πŸŽ€

Currently, none of XML::Simple's myriad of options are supported. Support for ContentKey, ForceContent, KeepRoot, SearchPath, and ValueAttr are planned for future releases. So like… hold your horses bestie, they're coming. 🐴


🌈 DTD CONFIGURATION 🌈

XML::Simple::DTDReader is able to deal with inline and external DTDs. Inline DTDs take the form:

  <?xml version="1.0" encoding="UTF-8" ?>
  <!DOCTYPE greeting [
    <!ELEMENT greeting (#PCDATA)>
  ]>
  <greeting>Hello, world!</greeting>

External DTDs are either "system" DTDs or "public" DTDs. System DTDs are of the form:

  <?xml version="1.0"?>
  <!DOCTYPE greeting SYSTEM "hello.dtd">
  <greeting>Hello, world!</greeting>

The path in the external system identifier "hello.dtd" is relative to the path to the XML file in question, or to the current working directory if the XML does not come from a file, or the path to the file cannot be determined. iykyk, paths are always a little dramatic. 😭

Public DTDs take the form:

  <?xml version="1.0"?>
  <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
            "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
  <svg>
    <path d="M202,702l1,-3l7,-3l3,1l3,7l-1,3l-7,4l-3,-1l-3,-8z" />
  </svg>

Two properties of the DTD are used by XML::Simple::DTDReader when figuring out the final structure of the data: repeated elements, and ID attributes. In the DTD, specifications of the form element+ or element* will lead to the key element mapping to an anonymous array. This is perhaps best illustrated with an example:

  <?xml version="1.0" encoding="iso-8859-1"?>
  <!DOCTYPE data [
    <!ELEMENT data (stuff+)>
    <!ELEMENT stuff (name,other*)>
    <!ELEMENT name  (#PCDATA)>
    <!ELEMENT other (#PCDATA)>
  ]>
  <data>
    <stuff>
      <name>Moose</name>
      <other>Value</other>
    </stuff>
    <stuff>
      <name>Thingy</name>
      <other>Value</other>
      <other>Value2</other>
    </stuff>
  </data>

...will map to the data structure:

  {
    stuff => [
              {
               name => "Moose",
               other => ["Value"],
              },
              {
               name => "Thingy",
               other => ["Value", "Value2"],
              }
             ]
  }

The other element of the DTD that impacts the data structure is ID attributes. In XML, ID attributes are unique across a file, which is a more general case of Perl's restriction that keys be unique in a hash. So basically: the presence of attributes of type ID will cause that layer of the data to be folded into a hash, using the value of the ID attribute as the key. Again, best illustrated by example:

  <?xml version="1.0" encoding="iso-8859-1"?>
  <!DOCTYPE data [
    <!ELEMENT data (stuff+)>
    <!ELEMENT stuff (name)>
    <!ATTLIST stuff attrib ID #REQUIRED>
    <!ELEMENT name  (#PCDATA)>
  ]>
  <data>
    <stuff attrib="first">
      <name>Moose</name>
    </stuff>
    <stuff attrib="second">
      <name>Thingy</name>
    </stuff>
  </data>

...will lead to the data structure:

  {
    stuff => {
              first => {
                        name => "Moose",
                        attrib => "first"
                       },
              second => {
                         name => "Thingy",
                         attrib => "second"
                        }
             }
  }

XML::Simple::DTDReader recognizes most ELEMENT types, with the exception of mixed data (#PCDATA intermixed with elements) or ANY data. Attempts to parse DTDs describing elements with these types will result in an error. So don't try it bestie, it will simply not slay. πŸ’€


⭐ ERROR HANDLING ⭐

XML::Simple::DTDReader is more strict than XML::Simple when parsing documents; not only must the documents be compliant, they must also follow the DTD specified. XML::Simple::DTDReader will die with an appropriate message if it encounters a parsing of validation error. dramatic? yes. necessary? also yes. πŸ’…


πŸ“ EXAMPLES πŸ“

See the t/ directory of the distribution for a number of example XML files, and the perl data structures they map to. go look, it's free real estate 🏠


πŸ™ˆ BUGS πŸ™ˆ

None currently known, but I'm sure there are several. (the author said it, not me 😭)


🫢 AUTHOR 🫢

πŸ’œ Contact Info

Alex Vandiver : alexmv@mit.edu

Copyright (C) 2003 Alex Vandiver. All rights reserved. This package is free software; you can redistribute it and/or modify it under the same terms as Perl itself.


and that's the whole page bestie ✨ this was perl v5.42.0, dated 2025-07-25, served fresh from DTDReader(3). mwah πŸ’– πŸŽ€ πŸ¦‹

πŸ“¦ where this page comes from