DOM
DOM
DOM-begrepet er interessant i forhold til HMTL på flere måter. W3C arbeidet lenge med å forsøke å få fram velformede HTML-formater (XHTML) for nettop å gjøre parsing og behandling enklere. De seneste åren er det HTML5 som har overtatt som en de facto standard. HTML5 er ikke nødvendigvis velformet. Vi kan ha tagger som ikke avsluttes (<img src="pic.png" alt="?">) og vi kan ha attributter som ikke har noen verdi (<p contenteditable>). Dette stiller større krav til parseren i nettleseren. Når vi bruker utviklerverktøy i nettleseren ser vi at elementene framstår som XML-korrekte når vi inspiserer HTML-strukturen. Heldigvis kan vi selvsagt skrive formelt korrekt-XML i HTML5, altså angi alle attributtverdier og avslutte tagger korrekt. Dette er en fordel for oss som ønsker å bearbeide våre vevsider via verktøy med enklere parsere enn de som er implemnterte i nettleserne.
Vi tar for oss en XML fil som beskriver sprintresultater fra de seneste olympiadene all_results.xml
Rent intuitivt kan elementene i et dokument beskrives slik:
Dette gir oss en grov ide av hva en DOM er, men i praktisk bruk er det ikke nok å ha et tre som bare har elementene. Vi har flere nodetyper å holde styr på, og et DOM-tre blir fort ganske omfattende. Nedenfor er en oversikt over alle mulige nodetyper og hva slags barn de kan ha i et DOM-tre:
Nodetype | Mulige barn |
---|---|
Document | Element (maks 1), ProcessingInstruction, Comment, DocumentType |
DocumentFragment | Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference |
DocumentType | ingen |
EntityReference | Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference |
Element | Element, Text, Comment, ProcessingInstruction, CDATASection, EntityReference |
Attr | Text, EntityReference |
ProcessingInstruction | ingen |
Comment | ingen |
Text | ingen |
CDATASection | ingen |
Entity | Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference |
Notation | ingen |
Merk at attributter ikke betraktes som barn av et element. DOM betrakter attributter som egenskaper ved et element. Et mer komplett DOM-tre vil således se slik ut:
Klassestruktur for DOM-noder
W3C definerer ikke bare strukturen i et DOM-tre. De har også definert en klassestruktur for å bearbeide DOM-trær. Hos W3C er denne klassestrukturen beskrevet i Java-syntaks. Grafisk kan klassestrukturen beskrives slik:
De hvite boksene beskriver klasser som er generelle for XML-dokumenter, mens de gule er de tilleggene som er nødvendig for å beskrive HTML-dokumenter spesielt.
Dette gir grunnlaget for hvordan et klassebibliotek for handtering av DOM-strukturer skal implementeres i et objektorientert språk som Java, C++, Python.
Funksjonalitet
Nedenfor finner du en list over metoder som er definert for de enkelte objeckttypene. Oversikten er psedudo-Java. Parametrene er utelatt og det angis ikke hvilke metoder som fører til exceptions. Hensikten er bar å gi en oversikt. For detaljer kan du se referansen som er angitt nedenfor.
public interface DOMImplementation { public boolean hasFeature(..); } public interface DocumentFragment extends Node { } public interface Document extends Node { public DocumentType getDoctype(); public DOMImplementation getImplementation(); public Element getDocumentElement(); public Element createElement(...) public DocumentFragment createDocumentFragment(); public Text createTextNode(...); public Comment createComment(...); public CDATASection createCDATASection(..) public ProcessingInstruction createProcessingInstruction(...) public Attr createAttribute(...) public EntityReference createEntityReference(...) public NodeList getElementsByTagName(...); } public interface Node { // NodeType public static final short ELEMENT_NODE = 1; public static final short ATTRIBUTE_NODE = 2; public static final short TEXT_NODE = 3; public static final short CDATA_SECTION_NODE = 4; public static final short ENTITY_REFERENCE_NODE = 5; public static final short ENTITY_NODE = 6; public static final short PROCESSING_INSTRUCTION_NODE = 7; public static final short COMMENT_NODE = 8; public static final short DOCUMENT_NODE = 9; public static final short DOCUMENT_TYPE_NODE = 10; public static final short DOCUMENT_FRAGMENT_NODE = 11; public static final short NOTATION_NODE = 12; public String getNodeName(); public String getNodeValue() public void setNodeValue(...) public short getNodeType(); public Node getParentNode(); public NodeList getChildNodes(); public Node getFirstChild(); public Node getLastChild(); public Node getPreviousSibling(); public Node getNextSibling(); public NamedNodeMap getAttributes(); public Document getOwnerDocument(); public Node insertBefore(...) public Node replaceChild(...) public Node removeChild(...) public Node appendChild(...) public boolean hasChildNodes(); public Node cloneNode(...); } public interface NodeList { public Node item(...); public int getLength(); } public interface NamedNodeMap { public Node getNamedItem(...); public Node setNamedItem(...) public Node removeNamedItem(...) public Node item(...); public int getLength(); } public interface CharacterData extends Node { public String getData() public void setData(...) public int getLength(); public String substringData(...) public void appendData(...) public void insertData(...) public void deleteData(...) public void replaceData(...) } public interface Attr extends Node { public String getName(); public boolean getSpecified(); public String getValue(); public void setValue(String value); } public interface Element extends Node { public String getTagName(); public String getAttribute(...); public void setAttribute(...) public void removeAttribute(...) public Attr getAttributeNode(...); public Attr setAttributeNode(...) public Attr removeAttributeNode(...) public NodeList getElementsByTagName(...); public void normalize(); } public interface Text extends CharacterData { public Text splitText(...) } public interface Comment extends CharacterData { } public interface CDATASection extends Text { } public interface DocumentType extends Node { public String getName(); public NamedNodeMap getEntities(); public NamedNodeMap getNotations(); } public interface Notation extends Node { public String getPublicId(); public String getSystemId(); } public interface Entity extends Node { public String getPublicId(); public String getSystemId(); public String getNotationName(); } public interface EntityReference extends Node { } public interface ProcessingInstruction extends Node { public String getTarget(); public String getData(); public void setData(...) }
Alle moderne språk har biblioteker som handterer DOM. I dette materialet vil du finne eksempler for Python og for Jacascript. Bibliotekene for Java og for .Net-språkene (C# og VB) er bedre utbygd.