Oracle Help for the WebContentsIndexSearchGlossaryView Topic


Writing Version Controllable XML

This topic collates a number of "best practices" for the format and content of XML files intended to be shared in a team. The information here should be useful even if you do not have control over the content of an XML file, because even the way XML files are formatted and updated can have significant effects on how version controllable they are.

The target audience of this topic is developers of any feature that generates XML-based files that will be shared in a team.

Rule 1: Avoid making implicit changes

This may seems obvious, but you should never change the content of a file unless the user explicitly edits the file using an editor. For example, do not change the workspace file when the user changes the selected project, or when the user just opens an editor on an XML file and doesn't actually change anything. This rule actually applies to all file types, not just XML.

Rationale:

Alternative solutions:

Rule 2: Avoid marking files "dirty" when they have not changed

This refers to making files appear unsaved, even when you have not actually changed the contents of the files.

Rationale:

Rule 3: Don't arbitrarily reorder elements inside an XML file

Some XML files are read into an internal data structure, then written back out to XML when the object is saved. If you are doing this, bear in mind that the order of certain data structures can change between uses. For example, if you store elements in a hashmap, the order of the keys will change depending on the contents of the map. Try to always ensure that the order of elements in the XML file is disrupted as little as possible.

Rationale:

Rule 4: Don't reformat XML files if the user can manually edit them

If the user is allowed to manually edit an XML file using a text editor, try to maintain the user's original formatting as much as possible when writing the file back out after an "automatic" change (that is, editing the XML file via a visual editor).

This rule applies to the entire formatting of the XML file, including comments, attribute order, indent size, number of tags per line, etc.

As an example, suppose a developer checks the following XML file out of CVS:

<?xml version="1.0" encoding="UTF-8"?>

<widget>
  <widget-instance><name>First Widget</name></widget-instance>
  <widget-instance>
    <name reskey="blah.name" resbundle="MyBundle" />
  </widget-instance>
</widget>    

If a visual editor for this XML file changes the name of the first widget, it should just change the name of the first widget, rather than writing out something like this:

<?xml version="1.0" encoding="UTF-8"?>

<!-- Generated by JDeveloper on 24-May-2004 -->
<widget>
   <widget-instance>
      <name>First Widget</name>
   </widget-instance>
   <widget-instance>
      <name resbundle="MyBundle" reskey="blah.name" />
   </widget-instance>
</widget>

    

The obvious exception to this rule is when the user explicitly asks to reformat the XML file (for example, by using JDeveloper's Auto Indent XML feature).

Rationale:

Rule 5: Separate XML elements and attributes onto separate lines

Each start element in the XML file should start on a new line. If any XML element has more than one attribute, split each attribute onto a separate line.

Example file:

<?xml version="1.0" encoding="UTF-8"?>

<widget
    xmlns="http://xmlns.oracle.com/widgets"
    id="first.widget"
    class="FirstWidgetClass">

  <!-- This is a comment about widget instance -->
  <widget-instance>
    <!-- This is OK, on one line because there is only one attribute -->
    <subwidget id="sub.widget" />
    <!-- This one has two attributes, so is split up.
    <subwidget
        id="sub.widget.2"
        name="SubWidget2" 
    />
  </widget-instance>

</widget>

    

Rationale:

Rule 6: Avoid magic values

XML is a versatile format that can be used to represent just about any kind of data. Sometimes, for reasons of coding efficiency, you may be tempted to store structured data in another format within an XML file. For team development, it's almost always better to use only an XML based representation, even if this does require a bit more work in code and makes the XML file slightly more verbose.

As an example, a piece of code was until recently using a bitmask, like this:

<?xml version="1.0" encoding="UTF-8"?>

<method 
    name="doSomething"
    modifiers="97"
    returntype="void"
...
</method>

</widget>    

It would be much better to encode the access modifiers directly in XML using either subelements or attributes, for example:

<?xml version="1.0" encoding="UTF-8"?>

<method 
    name="doSomething"
    returntype="void"
  <modifiers>
    <public />
    <final />
    <synchronized />
  </modifiers>
...
</method>

</widget>    

or:

<?xml version="1.0" encoding="UTF-8"?>

<method 
    name="doSomething"
    returntype="void"
  <modifiers
      public="true" 
      final="true"
      synchronized="true" 
  />
...
</method>

</widget>    

Another (bad) example:

<?xml version="1.0" encoding="UTF-8"?>

<shape>
  <graphical-properties>
    <font>Bold|16|MS Sans Serif</font>
  </graphical-properties>
</shape>


    

Rationale:

Rule 7: Sort elements to avoid conflicts

Some XML files contain a list of objects that can be created by the user. Each time the user creates a new object, a new element is added to the end of a set of existing elements in the XML file. If the order of these elements within the XML file is insignificant, consider using some attribute or subelement to sort the elements alphabetically in the file.

An example file containing five widgets:

 1: <?xml version="1.0" encoding="UTF-8"?>
 2: 
 3: <widgets>
 4: 
 5:   <widget name="Sigroid" />
 6:   <widget name="Plasmoid" />
 7:   <widget name="Obeloid" />
 8:   <widget name="Turboid" />
 9:   <widget name="Tetroid" />
10: 
11: </widgets>    

If two developers concurrently create new widgets called Karmoid and Randomoid and they're inserted at the end of the list, this will always cause an unresolvable merge conflict on line 10.

If however, we sort the widgets first, and always insert new widgets in their sorted order, both changes can be concurrently merged without a conflict:

 1: <?xml version="1.0" encoding="UTF-8"?>
 2: 
 3: <widgets>
 4: 
>>:   <widget name="Karmoid" />
 5:   <widget name="Obeloid" />
 6:   <widget name="Plasmoid" />
>>:   <widget name="Randomoid" />
 7:   <widget name="Sigroid" />
 8:   <widget name="Tetroid" />
 9:   <widget name="Turboid" />
10: 
11: </widgets>