The topic of designing documents is not the one that you can summarize in a short paragraph. As such, we will concentrate on three fundamental characteristics:
Descriptive- and data-oriented document structures:
These two styles of documents give the vast majority of XML documents. In this chapter we will examine the characteristics of these two styles, and when to use either.
Building blocks: attributes, elements and character data. Since there are many other features of an XML document, there are only a few that actually effects the design, legibility and interpretability, but the above three can do this.
Pitfalls: Data modeling is such a huge topic, a separate book could be written about it. So, instead of covering everything, we will try to focus on the pitfalls that can be the cause of serious problems while using your document.
The XML documents are usually used for two types of data modeling. The descriptive document structure uses the XML content to supplement existing text-based data, similar to the way HTML uses tags for web pages. As for data-oriented document structures, the XML content itself is the important data. In this chapter we will examine these two styles and check out a few examples of when we should use each of them.
Use data-oriented document structures for modeling well-structured data
As previously mentioned, the data-oriented structure of the document is the one, wherein the XML content describes the data directly, in other words, the XML markup is the important data in the document. Recall the previously mentioned XML example with the hospital beds.
<?xml version="1.0" encoding="utf-8"?> <account:persons xmlns:information="http://example.org/information" xmlns:account="http://example.org/schema/person"> <account:person> <name>John Doe</name> <age>23</age> <account:favourite> <number>4</number> <dish>jacked potato</dish> </account:favourite> <account:favouriteWebPage> <account:address>http://www.w3.org</account:address> </account:favouriteWebPage> </account:person> </account:persons>
This document uses XML to specify the characteristics of a person. In this case, the text content (aka the interpreted character data or just character data, we use these terms interchangeably) in the document is meaningless without the XML tags. You could also write:
<?xml version="1.0" encoding="utf-8"?> <account:persons xmlns:information="http://example.org/information" xmlns:account="http://example.org/schema/person"> <account:person name="John Doe" age="23"> <account:favourite number="4" dish="jacked potato"/> <account:favouriteWebPage address="http://www.w3.org" /> </account:person> </account:persons>
This document records the same data set as the first, but instead of using character data to give the values, it uses attributes. In this case, there is absolutely no character data and it is clear that the XML content itself is the data in this document. If we were to remove the XML content of the document, apart from the whitespaces, it would be empty. This document style is not what we are recommending for use in practice, in this case it only serves the purpose of comparison.
A further thought is that we could of course continue to convert all the content to attributes of the element person. In this case it is obvious that the XML markup is the only useful data in the document. We can see that there are many simple ways of encoding the same data.
All three documents are clear examples of data-oriented documents, also they all use XML markups to describe the well-structured data. With the help of the data inside the documents, you can imagine that the data is one-to-one mapped with the characteristics of our application, which makes the XML document the serialized version of our objects. This kind of serialization is very common in XML. We can also exploit the hierarchical nature of XML while describing more complex structures.
For this process, standard solutions have been integrated into many programming languages. Microsoft .NET Framework Common Library contains functionality that is suitable for serializing any class automatically, and deserializing any XML with the help of the class XmlSerializer in the package System.Xml.Serialization. The standard Java library does not contain similar classes, however there is an API which bears similar functionality. This API is part of the Java XML package, and it is named Java API for XML Binding (JAXB). It offers the possibility to map XML documents to Java classes back and forth, and makes it easy to validate Java objects stored in memory. The latter functionality of course requires the developer to provide DTD or XML Schemes.
Obviously, maintaining serialized data structure is not the only use of data-oriented documents. For Java Beans or any other data structures the mapping can be done easily as well. In addition, XML can be used to display other data that are not directly linked to a data structure. For example, the Apache Ant builder system also uses an XML file to describe processes, in this case, processes for creating software. Thus, a well-described process may be thought of as a well-structured data.
Overall, we can say that the data-oriented documents are great choices for any kind of well-structured data representation. Now, let us proceed and examine the descriptive documents that are less suitable for structured data.
Descriptive documents
The main difference between the descriptive document structures and data-oriented structures is that while the descriptive ones have been designed for user consumption, the data-oriented structures are usually made for applications to use. In contrast to data-oriented structures, the descriptive documents are usually texts that can be simply read by human beings, and those texts are just extended with XML tags.
The two essential characteristics that distinguishes a descriptive text from a data-oriented document are the following:
The content is not determined by the markup:
XML is generally not an integral part of the information provided by the document, but it extends the plain text in various ways.
The markups are less structured:
while the data-oriented documents are meant to describe a data set, and are strictly structured, the descriptive documents contain free-flowing text, which is meaningful content, such as any book or article. The data can be seen in these types of documents unstructured in the aspect that the markup in the document does not follow any strict or repetitive rule.
For example, the number and order of tags in an HTML document, inside the <body> tag are infinitely flexible, and different from document to document.
Probably the most obvious examples of descriptive documents (although not strictly XML) are HTML web pages that use HTML markup tags in order to make their pages' more colorful. Although this information is important and definitely enhances the reading experience (for example, it specifies the location, size and of color images and texts on the page), it should be noted that the relevant information is independent of the HTML markup. Just as you use HTML tags in HTML documents to specify appearance, XML markup is used for things, such as to provide explanations for definitions in the text.
Take an example of how you can use descriptive document structure in practice. If you imagine that a hospital would use XML to represent minutes spent during surgeries, it would look something like this:
<operation>
<preamble>
The operation started at <time type="begin">09:30</time> on <date>2013-05-30</date>.
Involved persons: <surgeon>Dr. Al Bino</surgeon> and <surgeon>Dr. Bud Light</surgeon>, assistent <assistent>Ella Vader</assistent>
</preamble>
<case>
Dr Al Bino using a <tool>lancet</tool> made an incision on the <incisionPont>left arm</incisionPont>.
</case>
...
</operation>
This example document clearly shows that the important part is only the description of the surgery by a simple and clear way. The XML markups gives some useful information to the text ( to the content) like the date of the surgery, the involved doctors and similar infos, but without these tags the content remains understandable (not like the previously mentioned data-oriented documents without the tags).
Descriptive documents could be useful in the following scenarios:
Displaying
the XHTML is a perfect example to indicate how could we use XML markups for descriptive documents to influence the appearance.
Indexing
applications could be achieved an effective highlight on descriptive documents by using XML markups to identify key elements inside. After all, it could be used for indexing - which could be done by a relational database or a specific software.
The document describing surgeries are a good example for it. All the key elements are marked, so indexing could be done based on it.
Annotations
applications could use XML to append annotations to an existing document. It makes possible to the users to mark the text without modifying it.
An XML document has many traits, but the three most fundamental that influence document design are elements, attributes and character data. They can be seen as the basic building blocks of XML and they are the keys for the way of good document design. (The secret of good quality hide in the knowledge of the proper use of them.)
Developers often face the decision whether to use attributes or elements for encoding data. There is no standard method or one best way to do this, often it’s just a question of style. In some cases, however, (especially when we are handling large documents) this choice can make a huge difference in terms of the performance by the way of data handling by the program.
It is impossible to think of every data type and data structure that might be stored in XML format. That is why it is impossible to make a list of rules that can always tell the designer when to use attributes or elements. But if we understand the difference between these two, we will be able to make the right decisions based on the operation requirements of our application. That is why the following comparison focuses on the difference between elements and attributes, but we must not forget that character data also play a crucial role.
The “Rule” of Descriptive Documents
Unlike in data-oriented document structures, here we have a very easy rule that tells us when to use attributes or elements: a descriptive text should be represented as character data, every text should be part of an element, and every other information about the text should be stored in attributes.
We can easily comprehend this if we think about the purpose of the
document markers: they provide extra meaning to the main text. Everything
that adds new content (like the <time> in the previous
hospital example) should be represented as an element, and everything that
just describes the text without giving any new content should be represented
as an attribute of that element. And finally, the content itself should be
stored as character data within the element.
Descriptive text became the content of an element, while the information about it became attributes.
Sometimes it is not a crucial decision whether to represent data as an element or as an attribute. However these two have very different behaviors, which can, in some cases, degrade the performance of our application. These are discussed in the following sections.
Processing elements requires more time and storage space than attributes, if we are to represent the same data in both formats. This difference is not much if we process only one element or one attribute. However, on a larger scale or when document size is a major factor (e.g. if we send it through on a network with low bandwidth) our XML documents have to be as small as possible and using a lot of elements may prove to be a problem.
Question about Space
Elements always have to contain XML markers, therefore they will always take more space than attributes. Let’s look at our patients’ address as an example:
<information:address> <information:city>Debrecen</information:city> <information:street>Kis utca 15.</information:street> </information:address>
This is a very simple XML encoding. If we want to make a C# or Java class according to this specification, we could use strings to store the data, and even the previously mentioned XML serialization would give us this result. This encoding requires 108 characters, not counting the spaces. We could, however, use attributes (along with the elements), and then we would be able to dispose of the end tags.
<information:address> <information:city v="Debrecen" /> <information:street v="Kis utca 15." /> </information:address>
This takes only 94 characters, even if it makes reading the document more complicated (we know that v means value, but someone might not). In addition to the less space, it saves us some processing time too, because we don’t have to deal with any free text contexts (character data). However, we should not use this method.
Let’s look at the example once more, this time using only attributes:
<information:address city v="Debrecen" street v="Kis utca 15." />
This is the shortest possible encoding, and it takes only 69 characters, not counting the spaces (which saved us an extra 36%). This was just a simple example; this technique can be much more useful in case of larger documents where records could contain multiple packets of data. Both the saved storage space and the less time our application takes to read and process the document can be crucial.
Utilizing this method can make significant differences even on a smaller dataset. The documents using attributes are almost 40% smaller than the ones using elements and 35% smaller than the mixed ones. The mixing technique only saved about 6%.
This clearly shows that attributes are worth using instead of elements, if size is an issue. We also shouldn’t forget that the size-problem not only appears when we are dealing with large documents, but also when our application uses and/or generates many smaller documents.
The storage space the elements need may also affect the memory, depending on the processing mode we are using. For example, DOM creates a new node for every element it finds in the data tree. This means that it has to build all parts of an element, which require additional memory space (and also processing time). Creating and storing attributes in a DOM tree requires much less, and some DOM parsers are able to optimize the application by not processing attributes until they are referenced. This leads to shorter processing time and reduced memory usage because attributes are using much less space as the same data represented as an element object in the DOM processing.
Question about Processing Time
Elements not only require much more storage space, but also require much more processing time than attributes (based on how the basic DOM and SAX parsers work). Processing attributes using DOM produces significantly less load as they are not processed until they are referenced. Creating objects instead would mean unnecessary additional work (allocation and cration).
As we can later see, this can add up really fast and make DOM unusable, because having lots of elements can make the document a thousand times greater as its optimal size. If our favorite DOM implement is well documented, we may be able to check its source code and see how fast it handles attributes and elements, if not, we have only one thing to do - simply testing it.
Using SAX, the elements show a more obvious hindrance. All loaded elements in a document call two different methods: startElement() and endElement(). Also, if (like in our previous example) we use character data for storing values, it means calling an additional method too. That means, if our document has many unnecessary elements, calling two or more methods when we only need one makes the processing much slower. On the other hand, attributes do not require calling any methods: they are sorted into a structure by SAX (namely: Attributes) and then they become arguments of the startElement() method. This kind of initializing saves the computer much work, and saves us much processing time.
Based on our empirical experience, we can state that attribute style encoding in SAX (based on 10.000 elements) results only a minimal forehead like its counter part, the element only style - which is underlines our initial thoughts. However, the mixed style performs as the worst one, increasing processing time with the added elements and attributes.
By using DOM, we can estimate that the attribute only style could result big savings. The practice show nearly 50% forehead in the processing time. The mixed style is the worst one in this scenario too.
Using large amount of elements in SAX the results are nearly the same in all variations but the mixed style is still the worst one - approximately double the time requires for it to reach the same result as an attribute based version - highlighting that the mixed style never the best if performance is a key factor.
Attributes are quite limited in regards to what data they can display. An attribute can only contain character value. They are absolutely unsuitable of receiving any structured data, unequivocally intended to short strings. In contrast, elements specifically fit to receive structured data because they may contain embedded elements or character data as well.
However we can store structured data in attributes but at this point, we have to write all the code to interpret the string. In some cases, it may be acceptable, for example it is life-like to store a date as an attribute. The parser code is likely to analyze the string that contains the date. This is actually a pretty clever solution because we can enjoy the benefits of the attributes in contrast with the elements, as well as the time to evaluate this is minimal, so it saves us XML processing time.
(It should be noted that this solution works very well with dates, because their format is general enough by using them as strings, so they do not require any special knowledge in the analysis. However, if you overuse this technique it will ruin the XML representation, so use it with caution.)
In general terms, it is not advisable to be too creative when encoding structured data into a string. This is not the best use of XML, and is not a recommended practice. However, clearly shows the lack of flexibility that attributes represent. If we use the attributes in this way, then we are probably not making the most of the potential of XML. Attributes perform very well in storing relatively short and unstructured strings – and this is why you should use them for most of the cases. If we find ourselves in a situation that is requires to keep a relatively complicated structure as a text in your document, you might want to store it as a character data which has a very simple reason: performance.
In addition to that very long strings as an attribute value are stylistically undesirable, could cause problems in the performance as well. Because attribute values are only string instances, the processor must hold the whole value in the memory all the time. However, the SAX way of it has only a minor problem with large character data because it wrapped into smaller chunks, which are then processed one at a time by the ContentHandler's characters() method. So you do not have to keep the whole string in the memory at the same time.
It is mostly a stylistic thing but there are some guidelines that will help you making the right choice. You should consider using character data when:
the data is very long
Attributes are not suitable to store very long values because the whole value should be kept in the memory at the same time.
large number of escaped XML characters are present
If we work with character data, we can use a CDATA section in order to avoid parsing. For example, using an attribute for a Boolean expression, we encounter something like this:
"a < b & b > c "
However, if we have use a CDATA section, we could have encoded the same string into a much more readable form:
<![CDATA[ a < b && b > c ]]>
data is short, but the performance is important and we use SAX
As we have seen in the mixed-style documents, character data are requires considerably less time to be digested during processing than attributes in the case of SAX.
You should consider using attributes when:
data is short and unstructured
That's what the attributes have been created for but be careful because it can degrade performance, especially in the case of large documents ( >100.000) using with SAX.
SAX is used and we want to see a simple processor code
It is much easier to process attribute data than character data. The attributes are available when we begin to parse the context of an element. Processing character data is not too complicated either but it requires some extra logic which can be a source of error - especially for novice SAX users.
In many cases, the data has an attribute (or a set of attributes) which serves to clearly distinguish from other similar types of data. For example, an ISBN number, or a combination of an author and the title of book can be used to identify book objects clearly.
Using attributes instead of elements simplifies the process of parsing in certain circumstances. For example, if there is no default constructor of the class that we reconstruct then you can use the keys as an attribute to simplify the creation of the object. Simply, because the data needed for object creation are located in the opening tag of the element and promptly available (thinking about a SAX processors). The code remain clean as well, because the method will not over helmed with different types of elements, so we can always know where we are and what we are processing currently.
In contrast, if keys are stored as elements, then it will be difficult to track its processing code. It became complex because continuously requires an extra examination that is just for determining the type of the element and tracking the information needed to proceed. This could result in a more complex and confusing code.
Similar situation arrives when we would like to validate the document's content. Sometimes, we want to perform a quick check on the document before going into deeper processing. This is especially useful for stratified, distributed systems: a small amount of validation performed at the beginning to save unnecessary traffic in the lower layers or in private networks ( like a procurer system checks the format and number of your credit card before your order is forwarded to the executor).
In these situations it is a huge help, if the identifier or key information available as an attribute and not as an element. The processing code can greatly simplify the process and the performance will also be much better because most of the content can be completely suppressed in the document, and the process can be completed quickly.
Ultimately, using attributes against elements is a stylistic issue because the same result can be achieved using either approach. However, there are situations when attributes has a clear advantages in identifying data. Shortly, when specifying document structure make sure you know which category it belongs to.
In contrast with the elements, there is no fixed order on attributes. It doesn't matter how we specify the attributes in a schema or in a DTD because there is no constraint or rule that specifies the order that attributes should follow. Because XML does not require any attribute precedence, avoid them in such situations where the order of the values is important. It is better to use elements than attributes because this is the only way how we can enforce that order.
The way, in which we modeling our data in XML, will affect virtually every aspect of how people and applications come into contact with these documents. It is therefore critical that the data, which is represented, make the interactions more efficient and hassle-free. So far talked about a very low level of modeling, dispute the fact which XML primitives (elements and attributes) are more appropriate for different situations. For the rest, we'll examine a bit higher level principals.
We should avoid planning for special platforms and/or processors
The best features of the XML are that it is portable and platform-independent. This makes it a great tool to share data in a heterogeneous environment. When documents are used to share data or communicate with an external application, the planning of the document becomes extremely important.
As a designer we have to take a lot of factors into consideration. For example: the price of changing the structure of the data. After released and written codes were made to this structure, changing it is almost forbidden. In fact, once we presented the document structure for the outside world, basically we lose every control over it. It’s also recommended to think about how the documents, which are appropriate for our structure, will be processed.
It’s never a good idea to prepare a document structure for a version of some processor. I don’t mean that we should design document, which adapts to a processing technology (like DOM, SAX or pull-processors), rather I mean we have made plans for a certain version, like if we would adjust our JAVA code to a specific VM. The processors are evolving, so there is a little point to optimize a certain implementation.
As a result, the best thing we can do as a document designer is to plan documents to meet the needs of those what it will serve. The structure of the document is a contract and nothing more, not an interface or an implementation. Therefore, it is paramount importance to understand the usage of those documents, which follow this structure.
Following the database approach, consider the case when, let’s say, we use massive or just line-oriented database interface. If our API will affect hundreds or thousands of rows in the database, then probably we would design it to use collections or arrays as parameters, because one database query which affects thousands of rows is considerably faster than loads of query which run on only one row. It’s not necessary to know SQL Server or Oracle to make a good decision in this situation.
Also when we are planning a document structure, it much more deserves to focus on the extensive use of technology rather than worry about the special characteristics of a certain implementation. It’s much more important to understand the general difference between the elements and attributes than to know whether a process implementation is optimized to work with a large number of attributes or not. To continue the example above, if we design a document structure, what we know that it will contain thousands of entries, it’s important to know whether the usage of the element would cause significant performance penalty in terms of disk usage or time, during which the document will be processed.
If the documents aren’t made only for our application, then we should definitely make sure we plan the structure of the document that it does not depend on any platform specific or processor specific implementations characteristic.
The underlying data model isn’t usually the best choice for XML
XML is often used in situations where it isn’t the permanent presentation form of the described data. Think about for example the XML based RPC, which is bound to web services. In the case of XML RPC, the parameters of the remote procedure, as well as the return value (if it exists) are described in XML in a SOAP compliant document. The fact that we used XML to remote execution it can be clearly seen that this is not the primary representation of the data – this is just a secondary representation, which is only for conversation.
In situations like these, where the XML only does the intermediate coding of the data, it’s often a good idea to rethink the data structure, instead of simply recycle the existing structure, like in the XML-based structure. Often, the base data model isn’t the most optimal for the XML.
We can refer again to the world of databases, where the most persistent storage, like the relational databases, simple files, object databases or something similar wasn’t designed with XML and its structure in mind. Each of them was created for special purposes; they have got their strengths and weaknesses in this point of view.
One of the most common uses of the XML is to describe data, which has permanent representation as a relational data in some kind of a RDBMS. Relational databases have a simple structure, which contains separate tables, what has connection points with each other that are only logical. These relationships are defined by the foreign keys. Using relational databases onto hierarchical data usually means that there is a data table, which represents the parent in a hierarchical relationship, and there is a separate table (or tables) representing the “children” in the relationship.
If we have to represents this table structure in an XML document, the result would be a useless document structure, which would provide needless complication and plus work for the processing task because it isn’t use one of the greatest features of XML: the ability to represent hierarchical data. Flat document structure can be beautifully achieved which hasn’t got anything to do with the true face of XML, like the following example:
<?xml version="1.0"?> <planet name="earth"> <record region="Africa" country="Mauritius" language="Bhojpuri" year="1983" females="99467" males="97609"></record> <record region="Africa" country="Mauritius" language="French" year="1983" females="19330" males="16888"></record> <record region="Europe" country="Finland" language="Czech" year="1985" females="42" males="36"></record> <record region="Europe" country="Finland" language="Estonian" year="1985" females="330" males="102"></record> <record region="Far East" country="Nepal" language="Limbu" year="1981" females="65318" males="63916"></record> <record region="Far East" country="Nepal" language="Magar" year="1981" females="107247" males="105434"></record> <record region="Middle East" country="Israel" language="Russian" year="1983" females="56565" males="44500"></record> <record region="Middle East" country="Israel" language="Yiddish" year="1983" females="101445" males="87775"></record> <record region="North America" country="Canada" language="English" year="1981" females="7521960" males="7396495"></record> <record region="North America" country="Canada" language="French" year="1981" females="3178190" males="3070905"></record> <record region="South America" country="Paraguay" language="Castellano" year="1982" females="91431" males="75010"></record> </planet>
If we were to take this structure and place it directly into an XML, we would get a document structure similar to the following::
<?xml version="1.0"?> <planet name="earth"> <region name='Africa"> <countries> <country name="Mauritius"> <languages> <language name="Bhojpuri" year="1983" females="99467" males="97609" /> <language name="French" year="1983" females="19330" males="16888" /> </languages> </country> </countries> </region> <region name="Europe"> <countries> <country name="Finland"> <languages> <language name="Czech" year="1985" females="42" males="36" /> <language name="Estonian" year="1985" females="330" males="102" /> </languages> </country> </countries> </region> ... </planet>
Its a lot more natural XML-structure where even the relations of the original database can be observed. This document is much easier to read than the previous one because it utilises the internal hierarchical structure of XML in order to represent data in a more natural way. Structuring documents in this way can also make the processing code easier and more efficient for documents.
The most important thing to bear in mind when designing the structure of the document is that it should be based on the abstract model that best describes what we would like to code. Not in any way should it rely on the implementation of the model in some other technology (Java, C++, etc.) There might be cases where the software implementation of the model is very similar to its XML implementation, but this is very rarely the case. This type of analysis usually helps to create a more XML-friendly data model, which results in larger documents with simpler processing codes as well as better performance during the processing.
Avoid large documents
One of the side-effects of using XML is the lot of extra work that goes hand in hand with coding. To be honest, XML is not the most efficient descriptive mechanism. Each data of the document is associated with the appearance of some marker. As a general rule, it is advisable to keep the size of the document as small as possible for several reasons:
although disk space is not costly, it is not advisable to waste it,
each and every bit of the document is going through an XML processor, consequently, the longer the document, the longer this process takes,
if the document is used as a means of communication such as a SOAP document for an XML-based web service, then the whole document needs to be sent out to the network.
Although the long names of elements and attributes can greatly affect the size of the document, this is not where we typically try to gain space from, when attempting to fit the size of the document into a reasonable range. It is recommended that one should make sure that the document remained easily readable. (It also must not be forgotten that these are the elements that will shrink to the smallest size in case of compression).
It is often effective to analyse the data getting into the document to avoid increasing the number of unnecessary bits. It is a common trend in XML coding to just send the whole for coding without actually reviewing it. We can think of the issue of derived data as an example. The same holds true in the case of replication as well. It is needless to transfer the whole database, it is enough to transfer the changes only. Mostly, temporary data also do not need coding. In Java, what is marked as transient will not automatically be serialized. Fields that store temporary states such as the cache or the interim states during a long-running computation are generally transient variables.
Of course, it is also not practical to shorten our document too much; it is always a balance to be kept between the current performance and future flexibility. We have to make our own decisions which observe the requirements of our own applications. With a little more attention to the data that are in our document compared to what is actually needed, we can make the size of our document smaller, which will make it easier to process and handle.
The last general rule is that we should avoid redundancy when building the structure of the document. This leads to the next issue.
Avoid the use of document structures overloaded with references
One of the most inconvenient points about writing an XML processing code occurs when the document structure to be processed contains a lot of references similar to the following:
<document> <anElement name="szulo" /> <anElement name="gyerek" parent="szulo" /> </document>
This example illustrates the use of references in a very simple way. We must not forget it though that references are merely text-based and their use is only supported by very few language elements, and it is usually the task of the application code to process and handle them.
References can of course be very useful under certain conditions in XML. For example, the Ant build system uses XML to describe the processes, and we use references in an Ant build file to specify the dependencies of the target. Here is a quick example:
<project name="MyProject" default="dist" basedir=".">
<description>
simple example build file
</description>
<!-- set global properties for this build -->
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="dist" location="dist"/>
<target name="init">
<!-- Create the time stamp -->
<tstamp/>
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
</target>
<target name="compile" depends="init" description="compile the source " >
<!-- Compile the java code from ${src} into ${build} -->
<javac srcdir="${src}" destdir="${build}"/>
</target>
<target name="dist" depends="compile"
description="generate the distribution" >
<!-- Create the distribution directory -->
<mkdir dir="${dist}/lib"/>
<!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
<jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/>
</target>
<target name="clean" description="clean up" >
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
</project>The processing of documents overloaded with references can be quite complicated, and depending on the size and structure of our document as well as the effort put into the references, the performance of our processing code may be damaged, and the code itself may become difficult to understand for others. The problem with the use of documents overloaded with references is that we have to release the references ourselves. (This holds true for DOM and SAX at least. XSLT, which is more advanced, has more robust mechanisms to release references).
However, the resolution of references is not an unbearably complicated technical problem. Usually the code writing is very simple, especially if the relationship is one-to-one or one-to-many. The real problem is that we have to keep a considerably large amount of „states” in the memory for the resolution during the whole process. It’s not a big deal if the document is small, but as the document size increases, so does the state size and it can be a problem after a certain point. (Just think about that if we use DOM for document processing, than it will be a serious problem due to DOM requires to keep the whole document in the memory.)
Let’s look at an example. Let's say you are working on a document that uses a lot of references in a simple, non-recursive parent-child relationship. In the document the parents will be listed before than the children.
<document> <parent name="parent1" /> <parent name="parent2" /> ... <gyerek name="child1_1" parent="parent1" /> <gyerek name="child2_1" parent="parent1" /> ... <gyerek name="child1_2" parent="parent2" /> <gyerek name="child2_2" parent="parent2" /> ... </document>
We need some information about the parents for processing children in order to successfully process the document. For instance, we have to check that every children have a reference for a valid parent (this is called as reference integrity). It is also possible that we need information about the parent’s attribute to process a child.
If the number of parents is relatively small, the extra place reserved for the parents in the memory will not crash our system. But it will complicate the code of a SAX parser due to we have to write a code which handles the data. Although the presence of a relatively large number of parents can significantly affect the processing performance of your code because the memory usage increases linearly with the number of elements in the parent document. Even, any collection used for the handling in the parsing code should be sized properly, or should be increased (vectors, list arrays) constantly which also consumes a lot of memory and processing time.
The problem of references can worsen if the referring elements come earlier than the referred ones. For instance, if we rewrite our document in such a way that children would come sooner than parents, the amount of data in the memory would be much higher. There will probably be at least as many children as parent, if not more. To successfully process the document in this case, we should keep the data of all children in the memory until we process their own parents. When we find a parent we want to process all of its children which also complicates the code for the processing.
Most of these reference problems could be avoided if our document uses one-to-one or one-to- many relations, taking advantage of the hierarchical nature of XML. The processing of hierarchical data against references may lead to a much better code and memory usage.
To continue our previous example, if we rewrite our parent-child document using hierarchical structure it would not only simplify but would led to a cleaner and more readable code:
<document>
<parent name="parent1">
<gyerek name="child1_1" />
<gyerek name="child2_1" />
</parent>
<parent name="parent2">
<gyerek name="child1_2" />
<gyerek name="child2_2" />
</parent>
...
</document>If the document is hierarchical then the current piece of the document contains the parent of a specific child node. Therefore, in order to get the kids processed, the only parent we need to keep in mind can be found in that text. When a parent gets out of context, it is guaranteed that there will not be more children related to this parent, so it is not needed to retain information about this parent. Another great advantage of this structure that it is much more readable by humans.
In the case of Ant, this cannot be exploited because it models such data which are in many-to-many relation and a specific compilation target can be dependent on any number of other targets and any target can be a dependency of any other target. In such situations, certainly not worth the hierarchically encoded data, as there is no general pattern to the relationship of targets.
When documents are being planned, strive to use hierarchy instead of reference. If we have to model such a data which requires references, try to imagine the parsing code in our head so at least the memory usage will be predictable during the processing time.