Tutorial: Understanding XML
This article is incomplete. You can help by filling in any blank descriptions. Further information might be found in a section of the discussion page. Please remove this message when no longer necessary. |
Contents
1. XML basics
XML, or eXtensible Markup Language, is a meta-language that describes information by breaking it down into smaller elements using tags: < >. In itself, it does nothing. It just helps organize data.
XML is often described in contrast to HTML. While HTML displays data, focusing on how it's supposed to look, XML defines and describes the information.
If we were running an online shop, we probably hooked up our site to a database that holds everything there is to say about the different items in our inventory. Assuming this was done in XML:
<store_inventory> <drinks> <name>Nuka Cola</name> <price>12 Caps</price> <description>Fortified with vitaminerals and health tonics.</description> </drinks> <weapons> <name>Nuka Breaker</name> <price>1200 Caps</price> <description>Crack open a cold one; revenge is best served cold.</description> </weapons> <snacks> <name>Yum Yum Deviled Eggs</name> <price>8 Caps</price> <description>Just like how Mother used to make it.</description> </snacks> </store_inventory>
In itself, listing our inventory in XML doesn't do anything, except wrap up the information in a plain-text format, divided in different elements according to the tags, ready to be used by software. <price> doesn't mean anything to a browser, so the site's software would need to be coded to display the information from the XML file.
Similarly, the Fallout 3/New Vegas engine is already coded to display information from XML files, albeit in its own specific way.
2. The rules of XML
An XML document consists of tags, enclosed in < and >. In our case, the tags and their meaning are defined by Bethesda. There are also Entities - hardcoded words that represent some value. For example, "&true;" and "&false;" represent boolean 1 and 0.
The following XML syntax rules must also be followed to produce valid code:
a) All elements must be closed with a closing tag:
<tag>content</tag>
or be a self-closing empty-element tag:
<tag/>
The latter is usually used in combination with attributes, see below.
b ) Tags are case-sensitive and must be properly nested:
<Tag> content </tag> : wrong <tag1><tag2> content </tag1></tag2> : wrong <tag1><Tag2> content </Tag2></tag1> : correct
c) All documents need to have a root tag: every document's structure starts with the one tag holding everything else.
<A> <B> </B> </A> <C> </C>
is incorrect because there are 2 elements, A & C, at root level.
<A> <B> <D> </D> </B> <C> </C> </A>
is correct.
The relationship between different elements of an XML document is often described as a family tree. Elements on the same level of the hierarchy are called 'siblings'. An element containing another is the 'parent' to it, and the other one's its 'child'. Grandparents and grandchildren exist too, so on and so forth.
d) Some information about the element can be parked inside the tag itself rather than in a sub-element. When this is done, it's called an attribute. For instance, an element defined as text below is identified by a singular name using an attribute:
<text name="NameOfTextElement"> </text>
Information that's parked in an attribute tends to be that type of meta-information, something unique to the element that wouldn't benefit much from being listed as a sub-element.
e) Comments that won't be processed can be added like this:
<!-- mycomment -->
Caution: There must not be two dashes in the middle of a comment:
<!-- This is an invalid -- comment -->
3. XML in Bethesda games: A Schema
Bethesda's Gamebryo games have their menus and HUD components organized in elements inside XML documents. The elements and their hierarchy are translated into what to display on-screen by the game's own XML parser. For that, it applies meaning to elements, the tags and what's between them. Most of Bethesda's XML has been documented at CS Wiki.
It divides Bethesda's XML elements in roughly 3 major types: object elements, property elements, and operator elements. These can all be seen in this excerpt from stats_menu.xml, lines 1415-1420:
<image name="stats_hunger_meter"> <locus> &true; </locus> <filename> Interface\Stats\rad_meter_bracket.dds </filename> <zoom> <copy src="parent()" trait="zoom"/> </zoom> ... </image>
The main element here declares that a new image component is added to the stats menu. These are what are called object elements, which introduce new objects to the menu or HUD. As a matter of course, these are immediately given a name with the name attribute, so that operator elements and NVSE functions can refer to them.
One level down, you can see that several things about this new component need specifying, such as which texture it uses (the <filename> tag), and its zoom percentage. Other properties included the dimensions and the position of the object element. Elements specifying the properties of object elements... are called property elements. Also known as traits.
A lot of times the content of a property element can be an absolute value, either numeric or a string such as that filepath. However, these values can also be calculated during the game session, copied from the properties of other object elements and/or manipulated by mathematical and conditional elements. In the example above, the image's zoom percentage is copied from that of its own parent. Elements that perform such 'live' operations on property elements are called operator elements. They often involve the use of the src and trait attributes, in order to refer to another property. Src will most likely refer to an object element or something global, while 'trait' will refer to the property.
There are cases of elements that fall a little outside of this overall division. One is the <include> element, which you can spot all over the vanilla files, inserting code from other documents:
<image name="stats_headline_h1"> <include src="line.xml"/> </image>
It's important to also point out that many documents may contain custom property elements. They're marked that way by starting them with an underscore. In themselves they're a mystery to the parser, but they can be referred to by name by operators and NVSE functions, and have operators as children, so they're good at holding values and doing intermediate calculations, in order to avoid longer formulas, and at interacting with your mod's scripts.
Eg, again from stats_menu:
<_meter_height> 38 </_meter_height> <!-- line 26 --> <height> <copy src="StatsMenu" trait="_meter_height"/> </height> <!-- various lines -->
3.1. Object Elements
<rect> defines a rectangular region on the screen. In itself it won't be visible, but its own properties affect any children it has. In the example below, the text element that is a child to the rectangle element inherits the <systemcolor> property.
<rect name="SneakMeter"> <id> &noglow_branch; </id> <systemcolor>&hudmain;</systemcolor> <width> 356 </width> <height> 34 </height>
<text name="sneak_nif"> <width>128</width> <height>128</height> <justify>¢er;</justify> </text> </rect>
<text>, as you can imagine, defines a text component.
<image> defines a rectangular area that is to be filled with a texture.
<image name="filled_checkbox"> <visible>&false;</visible> <alpha>0</alpha> <filename>Interface\Shared\Marker\glow_square_filled_small.dds</filename> <texatlas> Interface\InterfaceShared.tai </texatlas> <width>26</width> <height>26</height> <x>-20</x> <y>3</y> </image>
<nif> defines an animation, and is used in loading_menu.xml, as well as for the breath meter in the hud:
<nif name="BreathMeter"> <filename>Interface\HUD\AirTimer01.NIF</filename> <animation>Forward</animation> <visible>&false;</visible> <alpha>0</alpha> <width>64</width> <height>64</height> <systemcolor>&hudmain;</systemcolor> </nif>
<menu> is the root element of menu-related xml files.
<menu name="HUDMainMenu"> <class> &HUDMainMenu; </class> <stackingtype> &does_not_stack; </stackingtype> <visible>&false;</visible> ... and so on </menu>
Other object elements encountered in the game include <hotrect> and <template>. As an object element, <template> probably serves a similar function as custom property elements do: holding intel that can be re-used elsewhere. Unsure about the difference between <rect> and <hotrect> (see stats_menu.xml).
<template name="stats_list_template"> <hotrect name="stats_list_template_item"> <include src="list_box_template.xml"/>
3.2. Property Elements
Property elements, or traits, define the properties of their parent elements. They can have literal values (numbers, strings, entities such as &true; or &false;), or consist of formulas that use operator elements.
<width> 450 </width> vs <width> <copy src="screen()" trait="width" />
If an element contains 2 or more properties of the same type, the last one wins. If no property is defined in a context where it would be applicable, the standard value will be used, usually 0 or empty string. In-game, properties get updated if any of their properties change as a result of an engine calculation or a script command. For instance, changing a property with SetUIFloat or SetUIString will immediately reevaluate all properties that use it.
a) Size and Position
- <x> and <y> define the position of the parent element on the x & y axis on the screen
- <width> and <height> should be self-explanatory
- <locus> is a boolean element. If &true; the x/y positioning of the element's children will be relative to that of the element, if not it will be absolute.
b) Rendering
- <visible> is a boolean that toggles on or off the display of an element, as well as that of its children. A hidden element can't be clicked or moused over but can still be activated through script.
- <alpha> is a numeric element that determines its parent's transparency, values range from 0 to 255 (normal, full visibility)
- <depth> is a numeric element that determines precedence for overlapping elements. The element with the higher value will be drawn on top. By default, children have higher depth than parents.
- <clips> is a boolean that makes sure that if the parent's <clipwindow> property is true, the child element will be hidden if it's outside of the parent's dimensions.
- <systemcolor> takes entities, mostly &hudmain; which stands for the hud's main, 'pipboy' color
c) Clicking & Mousing Over
- <target> is a boolean element that determines if an element (rect or image) will react to player input. If true, the mouseover property will be set accordingly by the engine and if the element has an <id> property, clicking on it will set it to 'clicked' and play the specified clicksound.
- <clicked> is a numeric element that's set to 1 by the engine for a single frame after the element is clicked by the mouse.
- <clicksound> is a numeric element that determines which click sound effect is played when the element is clicked.
- <mouseover> is another numeric element that is automatically set to 1 by the game engine when the element has mouse focus. It is set to 0 otherwise.
d) Properties Unique to Image Elements
- <filename> specifies the filepath to the texture that the element will display, relative to the Data\Textures folder.
- <zoom> is a numeric element that specifies the zoom percentage. If larger than 100, it will magnify the source texture. If 0, it will hide the image. If -1, the image will be resized to fit the element's width and height instead of becoming cropped.
- <filewidth>, <fileheight> are read-only elements, set by the game engine to the actual width and height of the loaded texture (in pixels), after zoom has been applied. If zoom is -1, the value is 0.
- <tile> is a boolean element, if true and the width or height of the element is larger than the texture, 2 or more of the texture will be stacked together in a single image.
- <cropx>, <cropy> specifies the point of the texture that will be placed at the upper left-hand corner of the image. See here for an example.
- <texatlas> seems to refer to a .tai file, which unsurprisingly is a 'texture atlas', a file holding several textures.
e) Properties Unique to Text Elements
- <string> contains the text that is to be displayed.
- <red>, <green> and <blue> are numeric elements that you can use to specify the color of the text. Ranges from 0 to 255. (These also work on images!)
- <font> is a numeric element that stipulates which font is to be used according to the fonts listed in fallout.ini. If missing or invalid, it'll default to font 1.
- <justify> is an element that specifies where the text begins relative to the element's x coordinate. Values are "&left;", "¢er;" and "&right;".
- <wrapwidth> is the maximum width in pixels of the element. If the text exceeds this width it's split into multiple lines.
- <wraplines> is the maximum number of lines displayed.
See here for potential advanced use of the elements <IsHTML>, <PageNum> and <PageCount>, which should allow the display of text divided in pages.
f) Properties Unique to Menu Elements
- <class> specifies which internal menu class to use for handling in- and output to the menu. The values can be numeric and match the codes used by MenuMode, but are usually specified as entities matching the menu name, see Menu Classes.If a value is entered that doesn't correspond to a menu class, the menu will open but not be updated or accept input.
- <stackingtype> determines whether or not the menu blocks the use of other menus or the gameplay controls when it's open. Most do block such interaction and are marked as "&no_click_past;".
- <menufade> specifies the duration in seconds of the fade in/out effect when the menu is opened and closed. A menu doesn't update or accept input while it's fading.
g) General & Misc
- <id> is supposed to be somewhat related to a menu's <class> tag, in that it specifies which part of the menu's own class system the element corresponds to for the purpose of updating and accepting player input. The examples on the Oblivion schema page are limited to menu types unique to that game, and it is unclear just how <id> functions in the context of various Fallout menus.
- <user#> : element types starting with user aren't normally part of the XML Schema but can be recognized by specific menu classes. Like <id>, it seems their significance very much depends on the menu they're in. According to the talk page here, they seem to be meant as some sort of placeholders to be used instead of referring to a menu structure several levels down, which might be subject to modding.
Other unexplained property elements are listed here.
3.3. Operator Elements
a) How They Work
Operators perform certain operations on property elements, using either literal values
<rect> <!--object--> <x> <!--property--> <copy> 10 </copy> <!-- operator: 'copy' is necessary if you'll perform further operations --> <add> 5 </add> <!--operator--> </x> </rect>
or other properties as their second operand, with the 'src' and 'trait' attributes in a self-closing tag:
<rect name="thiselement"> <x> <copy> 10 </copy> <add src="anotherelement" trait="y" /> </x> </rect>
Multiple operations are possible on the same property, and they are performed from top to bottom. If you need a different precedence instead, you can nest them:
<rect name="thiselement"> <x> <copy> 10 </copy> <add src="anotherelement" trait="y" /> <mul> 2 </mul> <add> <copy> 10 </copy> <div src="anotherelement" trait="x" /> </add> </x> </rect>
b) Possible Values for 'src'
The most direct way of referring to another property to perform an operation with is to simply state its name.
<rect name="firstrect"> <x> 10 </x> </rect> <image name="firstimage"> <x> <copy src="firstrect" trait="x" /> </x> </image>
However, there are also 'relative' ways to refer to other properties, using values for 'src' that include me, parent, sibling(name), and child(name):
<y> <copy src="me()" trait="x" /> </y>
sets an element's y position to the same as its x position
<x> <copy src="parent()" trait="x" /> </x>
sets an element's x position to that of its parent
<width> <copy src="sibling(siblingsname)" trait="width" /> </width>
sets an element's width to that of a specified sibling. If the name of the sibling's omitted, it defaults to the sibling defined directly before it.
Child follows the same syntax in that you need to specify a name, but it will also find grandchildren and below. If multiple children, grandchildren etc exist with the same name, the last one specified in the xml will be chosen.
Lastly, src can also refer to certain global properties, most notably by using "screen()" and "io()". In the example below, a hud element is positioned at the far right of the screen, by setting its x position to the width of "screen()", minus the element's own width:
<image name="thisimage"> <width> 300 </width> <x> <copy src="screen()" trait="width" /> <sub src="me()" trait="width" /> </x> </image>
io() is an abbreviation for input/output, it serves as a means of communication between the XML parser and the game's GECK Scripts. Properties copied from io can be set in GECK script with SetUIFloat and SetUIString. Pretty important, if you plan to toggle elements or position them using scripts and possibly MCM settings.
<visible> <copy src="io()" trait="_MyModVisible" /> </visible>
means that the HUD component described by this element will be visible, if the custom property "_MyModVisible" has been toggled on with SetUIFloat in this script:
SetUIFloat "HudMainMenu\_MyModVisible" 1
Note that "_MyModVisible" variable does not need to be defined in the XML file when using io().
c) Common Operators
Math Operators:
<add>, <sub>, <mul> and <div> should be self-explanatory. Also available are <mod> (modulus) and <rand> (random number between 0 and the contents of <rand> </rand>)
Logical Operators:
These all return the entities &true; (standing for the number 2), or &false; (1, or any other number).
<onlyif> and <onlyifnot> condition the element before them. Example:
<systemcolor> <copy> &hudmain; </copy> <onlyifnot> <copy src="io()" trait="_MyModAltColorTrait" /> <eq> 1 </eq> <!-- superfluous, really --> </onlyif> </systemcolor>
<and>, <or>, and <not> should be fairly familiar.
When it comes to comparing numbers to values, there is <lt> (lesser than), <lte> (lesser than or equal to), <gt> (greater than), <gte>, <eq> (equals), and <neq> (not equal).
<min> and <max> set the property value to, respectively, the minimum or maximum of itself and what's between the tag. Example:
<x> <copy src="parent()" trait="x" /> <min> 200 </min> <!-- will be 200 or less --> </x>