XML::DOM(3)
π NAME π
XML::DOM(3) β okay bestie, this is the manual page for XML::DOM, a Perl module for building DOM Level 1 compliant document structures. β¨
β¨ SYNOPSIS β¨
use XML::DOM;
my $parser = new XML::DOM::Parser;
my $doc = $parser->parsefile ("file.xml");
# print all HREF attributes of all CODEBASE elements
my $nodes = $doc->getElementsByTagName ("CODEBASE");
my $n = $nodes->getLength;
for (my $i = 0; $i < $n; $i++)
{
my $node = $nodes->item ($i);
my $href = $node->getAttributeNode ("HREF");
print $href->getValue . "\n";
}
# Print doc file
$doc->printToFile ("out.xml");
# Print to string
print $doc->toString;
# Avoid memory leaks - cleanup circular references for garbage collection
$doc->dispose;
πΈ DESCRIPTION πΈ
Okay so this module extends the XML::Parser module by Clark Cooper. XML::Parser is built on top of XML::Parser::Expat, which is a lower level interface to James Clark's expat library. π
XML::DOM::Parser is derived from XML::Parser. It parses XML strings or files and builds a data structure that conforms to the API of the Document Object Model as described at http://www.w3.org/TR/REC-DOM-Level-1. See the XML::Parser manpage for other available features of the XML::DOM::Parser class.
Note, bestie: the 'Style' property should not be used (it is set internally). π
The XML::Parser NoExpand option is more or less supported, in that it will generate EntityReference objects whenever an entity reference is encountered in character data. Ngl, I'm not sure how useful this is. Any comments are welcome. π
As described in the synopsis, when you create an XML::DOM::Parser object, the parse and parsefile methods create an XML::DOM::Document object from the specified input. This Document object can then be examined, modified and written back out to a file or converted to a string. π«Ά
When using XML::DOM with XML::Parser version 2.19 and up, setting the XML::DOM::Parser option KeepCDATA to 1 will store CDATASections in CDATASection nodes, instead of converting them to Text nodes. Subsequent CDATASection nodes will be merged into one. Let me know if this is a problem. πΈ
When using XML::Parser 2.27 and above, you can suppress expansion of parameter entity references (e.g. %pent;) in the DTD, by setting ParseParamEnt to 1 and ExpandParamEnt to 0. See Hidden Nodes for details. β¨
A Document has a tree structure consisting of Node objects. A Node may contain other nodes, depending on its type. A Document may have Element, Text, Comment, and CDATASection nodes. Element nodes may have Attr, Element, Text, Comment, and CDATASection nodes. The other nodes may not have any child nodes. π¦
This module adds several node types that are not part of the DOM spec (yet.) These are: ElementDecl (for <!ELEMENT ...> declarations), AttlistDecl (for <!ATTLIST ...> declarations), XMLDecl (for <?xml ...?> declarations) and AttDef (for attribute definitions in an AttlistDecl.) π
π¦ XML::DOM Classes π¦
The XML::DOM module stores XML documents in a tree structure with a root node of type XML::DOM::Document. Different nodes in the tree represent different parts of the XML file. The DOM Level 1 Specification defines the following node types, bestie:
XML::DOM::Nodeβ super class of all node types.XML::DOM::Documentβ the root of the XML document.XML::DOM::DocumentTypeβ describes the document structure:<!DOCTYPE root [ ... ]>XML::DOM::Elementβ an XML element:<elem attr="val"> ... </elem>XML::DOM::Attrβ an XML element attribute:name="value"XML::DOM::CharacterDataβ super class ofText,CommentandCDATASection.XML::DOM::Textβ text in an XML element.XML::DOM::CDATASectionβ escaped block of text:<![CDATA[ text ]]>XML::DOM::Commentβ an XML comment:<!-- comment -->XML::DOM::EntityReferenceβ refers to anENTITY:&ent;or%ent;XML::DOM::Entityβ anENTITYdefinition:<!ENTITY ...>XML::DOM::ProcessingInstructionβ<?PI target>XML::DOM::DocumentFragmentβ lightweight node for cut & paste.XML::DOM::Notationβ anNOTATIONdefinition:<!NOTATION ...>
In addition, the XML::DOM module contains the following nodes that are not part of the DOM Level 1 Specification:
XML::DOM::ElementDeclβ defines an element:<!ELEMENT ...>XML::DOM::AttlistDeclβ defines one or more attributes in an<!ATTLIST ...>XML::DOM::AttDefβ defines one attribute in an<!ATTLIST ...>XML::DOM::XMLDeclβ an XML declaration:<?xml version="1.0" ...>
Other classes that are part of the DOM Level 1 Spec:
XML::DOM::Implementationβ provides information about this implementation. Currently it doesn't do much. πXML::DOM::NodeListβ used internally to store a node's child nodes. Also returned bygetElementsByTagName.XML::DOM::NamedNodeMapβ used internally to store an element's attributes.
Other classes that are not part of the DOM Level 1 Spec:
XML::DOM::Parserβ a non-validating XML parser that createsXML::DOM::Documents.XML::DOM::ValParserβ a validating XML parser that createsXML::DOM::Documents. It usesXML::Checkerto check against theDocumentType(DTD).XML::Handler::BuildDOMβ aPerlSAXhandler that createsXML::DOM::Documents.
π XML::DOM package π
π Constant definitions π
The following predefined constants indicate which type of node it is. Slay, let's list them:
UNKNOWN_NODE(0) β the node type is unknown (not part of DOM).ELEMENT_NODE(1) β the node is anElement.ATTRIBUTE_NODE(2) β the node is anAttr.TEXT_NODE(3) β the node is aTextnode.CDATA_SECTION_NODE(4) β the node is aCDATASection.ENTITY_REFERENCE_NODE(5) β the node is anEntityReference.ENTITY_NODE(6) β the node is anEntity.PROCESSING_INSTRUCTION_NODE(7) β the node is aProcessingInstruction.COMMENT_NODE(8) β the node is aComment.DOCUMENT_NODE(9) β the node is aDocument.DOCUMENT_TYPE_NODE(10) β the node is aDocumentType.DOCUMENT_FRAGMENT_NODE(11) β the node is aDocumentFragment.NOTATION_NODE(12) β the node is aNotation.ELEMENT_DECL_NODE(13) β the node is anElementDecl(not part of DOM).ATT_DEF_NODE(14) β the node is anAttDef(not part of DOM).XML_DECL_NODE(15) β the node is anXMLDecl(not part of DOM).ATTLIST_DECL_NODE(16) β the node is anAttlistDecl(not part of DOM).
Usage, bestie:
if ($node->getNodeType == ELEMENT_NODE)
{
print "It's an Element";
}
Not In DOM Spec: The DOM Spec does not mention UNKNOWN_NODE and, quite frankly, you should never encounter it. The last 4 node types were added to support the 4 added node classes.
π Global Variables π
$VERSION β the variable $XML::DOM::VERSION contains the version number of this implementation, e.g. "1.43". π
π METHODS π
These methods are not part of the DOM Level 1 Specification.
π getIgnoreReadOnly and ignoreReadOnly (readOnly)
Okay so the DOM Level 1 Spec does not allow you to edit certain sections of the document, e.g. the DocumentType, so by default this implementation throws DOMExceptions (i.e. NO_MODIFICATION_ALLOWED_ERR) when you try to edit a readonly node. These readonly checks can be disabled by (temporarily) setting the global IgnoreReadOnly flag. π
The ignoreReadOnly method sets the global IgnoreReadOnly flag and returns its previous value. The getIgnoreReadOnly method simply returns its current value.
my $oldIgnore = XML::DOM::ignoreReadOnly (1);
eval {
... do whatever you want, catching any other exceptions ...
};
XML::DOM::ignoreReadOnly ($oldIgnore); # restore previous value
Another way to do it, using a local variable:
{ # start new scope
local $XML::DOM::IgnoreReadOnly = 1;
... do whatever you want, don't worry about exceptions ...
} # end of scope ($IgnoreReadOnly is set back to its previous value)
π¦ isValidName (name)
Whether the specified name is a valid "Name" as specified in the XML spec. Characters with Unicode values > 127 are now also supported. β¨
π getAllowReservedNames and allowReservedNames (boolean)
The first method returns whether reserved names are allowed. The second takes a boolean argument and sets whether reserved names are allowed. The initial value is 1 (i.e. allow reserved names.) π«Ά
The XML spec states that "Names" starting with (X|x)(M|m)(L|l) are reserved for future use. (Amusingly enough, the XML version of the XML spec (REC-xml-19980210.xml) breaks that very rule by defining an ENTITY with the name 'xmlpio'.) A "Name" in this context means the Name token as found in the BNF rules in the XML spec. π
XML::DOM only checks for errors when you modify the DOM tree, not when the DOM tree is built by the XML::DOM::Parser. π
π setTagCompression (funcref)
There are 3 possible styles for printing empty Element tags:
- Style 0 β
<empty/>or<empty attr="val"/>.XML::DOMuses this style by default for allElements. - Style 1 β
<empty></empty>or<empty attr="val"></empty> - Style 2 β
<empty />or<empty attr="val" />. This style is sometimes desired when using XHTML. (Note the extra space before the slash/.) See<http://www.w3.org/TR/xhtml1>Appendix C for more details. π
By default XML::DOM compresses all empty Element tags (style 0.) You can control which style is used for a particular Element by calling XML::DOM::setTagCompression with a reference to a function that takes 2 arguments. The first is the tag name of the Element, the second is the XML::DOM::Element that is being printed. The function should return 0, 1 or 2 to indicate which style should be used to print the empty tag. E.g. π₯
XML::DOM::setTagCompression (\&my_tag_compression);
sub my_tag_compression
{
my ($tag, $elem) = @_;
# Print empty br, hr and img tags like this: <br />
return 2 if $tag =~ /^(br|hr|img)$/;
# Print other empty tags like this: <empty></empty>
return 1;
}
π IMPLEMENTATION DETAILS π
okay so this is the behind-the-scenes lore, bestie β the stuff that makes the whole thing actually work under the hood. no cap, itβs giving βdev notes but make it cute.β π
- Perl Mappings β The value
undefwas used when the DOM Spec saidnull.
The DOM Spec says: Applications must encode DOMString using UTF-16 (defined in Appendix C.3 of [UNICODE] and Amendment 1 of [ISO-10646]). In this implementation we use plain old Perl strings encoded in UTF-8 instead of UTF-16. iconic little shortcut, honestly β¨
- Text and CDATASection nodes β The Expat parser expands
EntityReferencesandCDataSectionsections to raw strings and does not indicate where it was found. This implementation does therefore convert both toTextnodes at parse time.CDATASectionandEntityReferencenodes that are added to an existingDocument(by the user) will be preserved.
Also, subsequent Text nodes are always merged at parse time. Text nodes that are added later can be merged with the normalize method. Consider using the addText method when adding Text nodes. little glow-up tip from the source itself π«Ά
- Printing and toString β When printing (and converting an XML
Documentto a string) the strings have to encoded differently depending on where they occur. E.g. in aCDATASectionall substrings are allowed except for"]]>". In regular text, certain characters are not allowed, e.g.">"has to be converted to">". These routines should be verified by someone who knows the details. so likeβ¦ if thatβs you, pls speak up bestie π - Quotes β Certain sections in XML are quoted, like attribute values in an
Element.XML::Parserstrips these quotes and the print methods in this implementation always uses double quotes, so when parsing and printing a document, single quotes may be converted to double quotes. The default value of an attribute definition (AttDef) in anAttlistDecl, however, will maintain its quotes. tiny quote drama, but we move π - AttlistDecl β Attribute declarations for a certain
Elementare always merged into a singleAttlistDeclobject. merged, not messy β we love a clean group chat π - Comments β Comments in the
DOCTYPEsection are not kept in the right place. They will become child nodes of theDocument. so yeah, location-wise theyβre kinda doing their own thing π - Hidden Nodes β Previous versions of
XML::DOMwould expand parameter entity references (like%pent;), so when printing the DTD, it would print the contents of the external entity, instead of the parameter entity reference. With this release (1.27), you can prevent this by setting theXML::DOM::ParseroptionsParseParamEnt => 1andExpandParamEnt => 0.
When it is parsing the contents of the external entities, it DOES still add the nodes to the DocumentType, but it marks these nodes by setting the 'Hidden' property. In addition, it adds an EntityReference node to the DocumentType node. sneaky but intentional, iykyk π₯
When printing the DocumentType node (or when using to_expat() or to_sax()), the 'Hidden' nodes are suppressed, so you will see the parameter entity reference instead of the contents of the external entities. See test case t/dom_extent.t for an example.
The reason for adding the 'Hidden' nodes to the DocumentType node, is that the nodes may contain <!ENTITY> definitions that are referenced further in the document. (Simply not adding the nodes to the DocumentType could cause such entity references to be expanded incorrectly.) protecting the entity lore, fr fr π¦
Note that you need XML::Parser 2.27 or higher for this to work correctly.
β¨ SEE ALSO β¨
XML::DOM::XPath- The Japanese version of this document by Takanori Kawai (Hippo2000) at
<http://member.nifty.ne.jp/hippo2000/perltips/xml/dom.htm>shoutout Hippo2000! πΈ - The DOM Level 1 specification at
<http://www.w3.org/TR/REC-DOM-Level-1>the sacred text β - The XML spec (Extensible Markup Language 1.0) at
<http://www.w3.org/TR/REC-xml>also sacred, also text π - The
XML::ParserandXML::Parser::Expatmanual pages. XML::LibXMLalso provides a DOM Parser, and is significantly faster thanXML::DOM, and is under active development. It requires that you download the Gnome libxml library. speed demon alert π₯XML::GDOMEwill provide the DOM Level 2 Core API, and should be as fast asXML::LibXML, but more robust, since it uses the memory management functions of libgdome. For more details see<http://tjmather.com/xml-gdome/>. robust + fast = main character energy π
π«Ά CAVEATS π«Ά
The method getElementsByTagName() does not return a "live" NodeList. Whether this is an actual caveat is debatable, but a few people on the www-dom mailing list seemed to think so. I haven't decided yet. It's a pain to implement, it slows things down and the benefits seem marginal. Let me know what you think.
so likeβ¦ is it a caveat? is it a vibe? the author is literally asking you. send thoughts. π
π AUTHOR π
Enno Derksen is the original author. respect the OG π
Send patches to T.J. Mather at <tjmather@maxmind.com>. patch mail, not hate mail, bestie π¬
Paid support is available from directly from the maintainers of this package. Please see <http://www.maxmind.com/app/opensourceservices> for more details.
Thanks to Clark Cooper for his help with the initial version. collab of the year, honestly π«Ά
source/version tea: perl v5.42.0 Β· page date: 2022-05-23 β k bye bestie, go parse something iconic ππ
π¦ where this page comes from
- opensuse-leap 16.0: perl-XML-DOM 1.46-160000.2.2 Β· Artistic-1.0 OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms