Business Website Links
Website Design, PR, and Surveys
Your One-Stop Shop for the
Internet & Beyond

Home Company Info Pricing Contact Client Directory Computer Tips News Testimonials

Computer Tips










Visit us often.  Computer tips updated daily.  Click here to--> "Tell a friend" so they can get updated computer tips, too.  Please visit our clients, as they support the computer tips page.

If you would like to submit a tip send us an email with your tip to

Tip: Remove unwanted whitespace from your result text document with XSLT

  • When transforming XML data into a text document, often unwanted whitespace nodes (e.g., extra line breaks) appear in the output. You can control this by using the <xsl:strip-space> element.
  • The <xsl:strip-space> element is a top-level element, and must follow immediately after the <xsl:stylesheet> start tag:
    • <xsl:stylesheet xmlns:xsl="" version="1.0">
    • <xsl:strip-space elements="*"/>
  • Selecting "*" will strip extra whitespace from all elements. You can limit this to specific elements by including the element names, separated by spaces like so:
    • <xsl:strip-space elements="para section topic"/>
  • Note that <xsl:strip-space> doesn't strip extra space within text nodes (e.g., textual content in a tag), unless there is no other textual content in the tag.

Tip: Streamline your XML Schema with substitution groups

  • Creating reusable content models is an important part of Schema design. Substitution groups provide one method to streamline your Schema and add flexibility to your model. They consist of a head element and one or more member elements. Any place the head element is referenced in your Schema, the member elements can be substituted for it. In fact, the head may be set simply as a placeholder as we'll see below.
  • Let's define an element named "para-sec":
    • <xsd:element name="para-sec" abstract="true"/>
  • Setting the abstract attribute to "true" means that the element para-sec will never appear as a tag in your data. Only the elements that are included in the para-sec substitution group will be available.
  • Next, define the elements you want to include in the substitution group. We'll set up para to handle standard paragraph content, table-para to include tabular data, and section to handle titled sections (which contain paragraphs). Use the substitutionGroup attribute to enable you to substitute these elements for para-sec wherever it's referenced in the Schema.
    • <xsd:element name="para" substitutionGroup="para-sec" type="paracontent"/>
    • <xsd:element name="table-para" substitutionGroup="para-sec">
    • <xsd:complexType>
    • <xsd:sequence>
    • <xsd:element ref="table"/>
    • <xsd:element ref="tablenote" maxOccurs="unbounded"/>
    • </xsd:sequence>
    • </xsd:complexType>
    • </xsl:element>
    • <xsd:element name="section" substitutionGroup="para-sec">
    • <xsd:complexType>
    • <xsd:sequence>
    • <xsd:element ref="title"/>
    • <xsd:element ref="para-sec" maxOccurs="unbounded"/>
    • </xsd:sequence>
    • </xsd:complexType>
    • </xsd:element>
  • Now you can reference the substitution group as the content model in other elements:
    • <xsd:element name="topic">
    • <xsd:complexType>
    • <xsd:sequence>
    • <xsd:element ref="title"/>
    • <xsd:element ref="para-sec" maxOccurs="unbounded"/>
    • </xsd:sequence>
    • </xsd:complexType>
    • </xsd:element>
  • The topic element can now contain an initial title followed by one or more of any members of the para-sec substitution group, in any order. Adding new members to the group automatically makes them available to "topic" in this instance.

Tip: Define a reusable attributeGroup in your XML Schema

  • In XML Schema, you can set up an attribute group to share a common attribute set with any number of elements. For example, you might want to include id, creation date, and revision date attributes on all major elements in your data set.
  • First, set up an attributeGroup like so:
    • <xsd:attributeGroup name="attlist-idgroup">
    • <xsd:attribute name="id" use="required" type="xsd:ID"/>
    • <xsd:attribute name="creation-date"/>
    • <xsd:attribute name="revision-date"/>
    • </xsd:attributeGroup>
  • This group defines "id" as required and of the type "xsd:ID". The creation-date and revision-date attributes have no further definition, which then defaults to implied with a type of "string".
  • You can then add this attribute group to an element like so:
    • <xsd:element name="article">
    • <xsd:complexType>
    • <xsd:complexContent>
    • <xsd:extension base="articleContent">
    • <xsd:attributeGroup ref="attlist-idgroup"/>
    • </xsd:extension>
    • </xsd:complexContent>
    • </xsd:complexType>
    • </xsd:element>
  • This example assumes a predefined complexType named "articleContent". It then utilizes an <xsd:extension> to call "articleContent" and add the "attlist-idgroup" attributeGroup to it. You can then apply this same method to each element needing to use this attributeGroup.
  • You can also add the attributeGroup directly to the content model of a given element:
    • <xsd:element name="appendix">
    • <xsd:complexType>
    • <xsd:sequence>
    • <xsd:element ref="title"/>
    • <xsd:element ref="para" maxOccurs="unbounded"/>
    • </xsd:sequence>
    • <xsd:attributeGroup ref="attlist-idgroup"/>
    • </xsd:complexType>
    • </xsd:element>
  • In this way, you simply define the sequence followed by the attributeGroup. You can add attributeGroups where individually defined attributes are used.

Tip: Manipulate the DOCTYPE to validate subsets of XML documents

  • A common misconception, especially among some folks with little XML experience, is that once you specify a DOCTYPE for a data set, that is the one you must always use, even if you're working with a subset of the document. This often leads to extracting the subset you want, adding upper level wrappers to match the DOCTYPE, and finagling things to get it to parse. Others will write custom DTDs to handle the subset.
  • It isn't necessary to jump through these hoops. Remember that the DOCTYPE declaration names the root element and points to the cooresponding DTD. The key here is that it points to the root element of the *document*, not the first element defined in the DTD.
  • For example, a journal DTD may define its upper content model like this:
    • <!ELEMENT journal (front, article+, appendix) >
  • So the DOCTYPE for the full data set would be:
    • <?xml version="1.0" encoding="utf-8"?>
    • <!DOCTYPE journal SYSTEM "journal.dtd" >
  • However, say you want to send just a single article to a customer, but they want to be able to validate it against the DTD. You don't need to modify the DTD or add upper level wrappers to the article; just change the DOCTYPE from "journal" to "article".
    • <?xml version="1.0" encoding="utf-8"?>
    • <!DOCTYPE article SYSTEM "journal.dtd" >
  • It reads the same DTD, but only those elements which fall within the given DOCTYPE. It ignores the rest. That's all there is to it. This is true even if you include the DOCTYPE in the DTD itself; you can still specify a specific element to start parsing from.

Tip: Use xsl:include to modularize your XSL stylesheets

  • Stylesheets can quickly become complex, especially if your data model contains a lot of elements and attributes. A good programming practice is to modularize your code into reusable components.
    The stylesheet below uses xsl:include elements to modularize the stylesheet. In this scenario, the xsl:template rules for your table's data model, defined in tables.xsl, are made available to the stylesheet processor.
    • <?xml version="1.0"?>
    • <xsl:stylesheet version="1.0"
    •  xmlns:xsl="">
    • <xsl:include href="table.xsl"/>
    • <xsl:template name="/">
    • <xsl:apply-templates/>
    • </xsl:template>
    • </xsl:stylesheet>
  • Take care to note the difference between xsl:import and xsl:include. Use xsl:include when you want to modularize your XSL transformation. Use xsl:import when you want to customize and override an existing XSL transformation.

Tip: Resolve namespaces in your XSL Stylesheets

  • If you're using XSL to transform or format your XML, it's important that you know how to handle XML Namespaces in your applications.
    You might find that your templates are producing unexpected results.
    • Listing A:
      • XML bound to a namespace
      • <?xml version="1.0"?>
      • <root xmlns="">
      • <child></child>
      • </root>
  • The XSL Stylesheet below matches the root of the XML document and applies templates for elements in the order they occur. The second template matches the root element and outputs text indicating the element has been matched. When you process the XML using this stylesheet, there's no output.
    • Listing B:
      •  XSL Stylesheet
      • <?xml version="1.0"?>
      • <xsl:stylesheet version="1.0" xmlns:xsl="">
      • <xsl:template match="/">
      • <xsl:apply-templates/>
      • </xsl:template>
      • <xsl:template match="root">
      • <xsl:text>xsl:template match="root"</xsl:text>
      • </xsl:template>
      • </xsl:stylesheet>
  • When you process the stylesheet against the XML, the output is shown below.
    • Listing B output using Saxon 6.5.3:
      • <?xml version="1.0" encoding="utf-8"?>
    • Listing B output using Xalan 2.6.0:
      • <?xml version="1.0" encoding="UTF-8"?>
  • In a more general case, you may find that elements or attributes aren't being matched as you expected. Your stylesheet needs to be aware of any namespaces that might exist in the XML. The stylesheet below illustrates how an XSL processor matches an element that's bound to a namespace in the source XML document.
    • Listing C:
      •  XSL Stylesheet with namespace support
      • <?xml version="1.0"?>
      • <xsl:stylesheet version="1.0" xmlns:xsl="" xmlns:result="">
      • <xsl:template match="/">
      • <xsl:apply-templates/>
      • </xsl:template>
      • <xsl:template match="root">
      • <xsl:text>xsl:template match="root"</xsl:text>
      • </xsl:template>
      • <xsl:template match="result:root">
      • <xsl:text>xsl:template match="result:root"</xsl:text>
      • </xsl:template>
      • </xsl:stylesheet>
    • Listing C output using Saxon 6.5.3:
      • <?xml version="1.0" encoding="utf-8"?>xsl:template match="result:root"
    • Listing C output using Xalan 2.6.0:
      • <?xml version="1.0" encoding="UTF-8"?>
        xsl:template match="result:root"

Tip: Look up special characters, symbols, and entities

  • Parsed character entities are often used to represent special symbols, for example, the named character entity &trade; can be used to represent the trademark symbol (). Listing A illustrates an entity declaration for the trademark character in a DTD.
    • Listing A: Trademark Entity Declaration
    • <!ENTITY trade "&#38;#x2122;"> <!-- TRADE MARK SIGN -->
  • In this example, the name of the entity is 'trade'. The hexidecimal value of this entity is '2122'. Complex schemas and DTDs often include hundreds of entity declarations for special characters and symbols that are used in XML instances.
  • You may come across character entities in your XML that you need to identify or troubleshoot. For example, special characters that don't render properly by an application are often described as 'upside-down question marks' or 'square boxes'.
  • To troubleshoot problems with special characters, a number of resources are available to you on the internet. The Unicode website ( offers resources and information for thousands of different languages and symbols.
  • If you're having problems with a character rendering properly, you can troubleshoot in a number of different ways. You can open the XML file in a Unicode-aware text editor. Is the symbol declared and referenced as a named character entity (&trade;) or the encoded character ()? Open the XML file in a hexidecimal editor and locate the problem character. Record the hex value for the character that isn't rendering properly and look it up online. Is the hex value correct? We suggest you use named entities in your source XML because it allows you greater control of the encoding in your output.
  • Point your favorite web browser to and click on Character Search. The Zvon Character search allows you to search for special symbols in a number of ways, including entity, hexidecimal, or decimal values.
Tip: Apply a CSS Stylesheet to your XML files
  • CSS is not just for HTML. When you need a quick glimpse of your XML in a more "format-friendly" presentation, you can easily use Cascading Style Sheets to view the XML. CSS is a simple stylesheet mechanism that allows you to attach styles to XML-based content. Listing A shows an XML file that contains information about a purchase order. The xml-stylesheet processing instruction applies the CSS Stylesheet called po.css to the XML. Listing A: po.xml
    • <?xml version="1.0"?> <?xml-stylesheet href="po.css" type="text/css"?>
    • <purchaseOrder
    • xmlns:xsi=""
    •  xsi:schemaLocation=" po.xsd">
      •  <billTo>
        • <name>Robert Smith</name>
        • <street>18 Park Avenue</street>
        • <city>Some Town</city>
        • <state>AR</state>
        • <zip>95819</zip>
      • </billTo>
      • <Items>
        • <item partNum="833-AA">
          • <productName>Lapis necklace</productName>
          • <quantity>2</quantity>
          • <price>99.95</price>
          • <comment>Need this for the holidays!</comment>
          • <shipDate>2005-12-05</shipDate>
        • </item>
        • <item partNum="748-OT">
          • <productName>Diamond heart</productName>
          • <quantity>1</quantity>
          • <price>248.90</price>
          • <comment>Valentine's day packaging.</comment>
          • <shipDate>2005-02-14</shipDate>
        • </item>
      • </Items>
    • </purchaseOrder>
  • The CSS Stylesheet for this XML uses a wildcard selector to match all elements. The result is each element displays as its own block. The content of the name element appears bold. This CSS stylesheet also illustrates the cascading nature of CSS. Notice the margin is set at the root element level and all descendant elements inherit the margin-left property.
  • Listing B: po.css
  • /*
  • css style rules for purchaseOrder xml
  • */
  • *{
  • display: block;
  • } purchaseOrder{
  • margin-left: 1em;
  • }
  • name{
  • font-weight: bold;
  • }

Tip: Use XML Catalogs for parsing XML

  • When working with XML, you often see references to external files or entities, either parsed or unparsed. XML Catalogs provide an "interoperable way to map the information in an XML external identifier into a URI reference for the desired resource."
  • Most XML applications allow you to create a catalog file to resolve references to external resources. A catalog provides your application with a list of formal system identifiers to be used for validation against a DTD or schema.
  • Let's say your XML file contains a reference to a Schema located on your company's web server.
    • <?xml version="1.0"?>
    • <!DOCTYPE myxml PUBLIC "-//My Company//DTD My Schema//EN"
    • "">
  • In order to parse and validate the content of this XML, the Schema needs to be available to the application. Well, if you're working offline, this can be a problem. Luckily, you can use an XML Catalog to address this problem.
  • An XML Catalog entry for the above XML file might look something like this:
    • <catalog>
    • <public publicId="-//My Company//DTD My Schema//EN"
    • uri="file:///C:/xml/schema/myschema.xsd"/>.
    • </catalog>
  • Your application can use this catalog file to resolve references to external resources. In this case, your application will validate your XML file against the locally saved copy of myschema.xsd. The DTD or schema may exist on a remote server, but validation must occur regardless of whether the user is locally disconnected.
  • For more information about XML Catalogs, please refer to the website.

Tip: Define element occurrence options in Relax NG

  • To determine how often an element can occur, DTDs use symbols
  • (e.g., *, +, ?) and XML Schemas use attributes
  • (e.g., minOccurs, maxOccurs). Relax NG is more, well, straightforward.
  • In Relax NG, to state that a tag may be used zero or more times, place a wrapper tag around it called <zeroOrMore>:
    • <zeroOrMore>
    • <element name="mytag">
    • <text/>
    • </element>
    • </zeroOrMore>
  • Similarly, for one or more occurrence, use the <oneOrMore> wrapper
    around the target element:
    • <oneOrMore>
    • <element name="mytag">
    • <text/>
    • </element>
    • </oneOrMore>
  • And then for optional elements, you use the <optional> wrapper:
    • <optional>
    • <element name="mytag">
    • <text/>
    • </element>
    • </optional>
  • Note that if there isn't an occurrence indicator on an element that it is required and can only occur once.

Tip: Save re-keying DTD element values with parameter entities

  • In DTDs, parameter entities provide a handy way to reuse a common content model across multiple elements.  For example, you can define an entity call "%text;" to describe elements that can appear in running text and then reference this entity in any element that contains only text and running text elements, as in:
    • <!ENTITY % text (#PCDATA | sub | sup | quote | emph | frac)* >
  • Now, instead of repeating this set of tags for each parent element, you can simply insert an entity reference, as follows:
    • <!ELEMENT title %text; >
    • <!ELEMENT para %text; >
    • <!ELEMENT term %text; >
    • <!ELEMENT definition %text; >

Tip: DTD/XSD change management:  Keep everyone in the loop

  • It's important to keep schema modifications to a minimum.  The schema constitutes a contract with the end users, and any change impacts processes built upon the content model.  If a change is called for, perform a benefit and cost analysis to determine the impact on all possible end users, including XML editors, programmers, vendors, business partners, and so forth.  this will allow you to make responsible decisions and establish appropriate timetables for implementation.  When you decide to implement a change, be sure to notify all affected parties in advance (e.g., 30 days, 60 days, six months) so they can account for the changes in their own systems/processes.

Tip: Subject matter experts and schema development

  • When designing a schema for XML content, don't underestimate the value of subject matter experts (SME) in developing a vocabulary that accurately reflects the content and structure of the information.  While you may have a better grasp of the technical requirements, the SMEs will mostly likely understand the content and authoring requirements more.  Depending on what type of content is being defined, the subject matter experts can play a significant role in a defining schema vocabulary.  This is especially true if the vocabulary runs deeper than just structural or functional elements and contains content-based element definitions as well.  Incorporating the knowledge of both your subject matter experts and your technology experts is important in schema design.  It's often not a either/or proposition.  Effective communication and education on both sides is key.

Tip: XML DTD: Use an "or" construction inside an "and" group

  • In an XML DTD, you can use an "or" construction inside an "and" group to give your content more flexibility while maintaining a tight structure.  Sounds like a contradiction, but it isn't really.  Suppose you have a document that you want to always contain a title, followed by one or more paragraphs, then a table or a graph, and end with a summary.  You could simply define the content model to list table followed by graph and make them both optional:
    • <!ELEMENT doc (title , para+ , table? , graph? , summary) >
  • Since both the table and graph are optional, you can just include the one you want and ignore the other.  However, this model makes it possible for an author to either omit the table/graph entirely or to include both, neither of which you want.  On the other hand, you can define an "or" construction inside the "and" group, like so:
    • <!ELEMENT doc (title , para+ , (table | graph) , summary) >
  • This content model describes your requirements exactly.  By enclosing the "table | graph" in parentheses, you're defining it as a single entry in the "and" group.  This allows either a table or a graph the document, but not both in the same document.  If you omit the parentheses, it will be an invalid DTD structure.  Using the "or" group in this way, you give yourself the ability to use either a table or a graph, but only in the specified location.  You've added flexibility to your content model, without sacrificing your tight structure to do so.

Tip: Using unordered element sets in XML schema (XSD)

  • In XSD, you can use xsd:all in a complexType to define a situation where all elements are required, but order doesn't matter.  For example, if you want to create a set of required contact elements (telephone, fax, email) that can occur in any order, you could set up a complexType in XSD this way:
    • <xsd:complexType name ="econtactType">
    • <xsd:all>
    • <xsd:element name="telephone" type="xsd:string"/>
    • <xsd:element name="fax" type="xsd:string"/>
    • <xsd:element name="email" type="xsd:string"/>
    • </xsd:all>
    • </xsd:complexType>
  • Note that xsd:all must contain only elements and only one of each element.  Any additional elements or attributes within the same complexType must come after xsd:all, not before or inside.

Tip: Should you use an element or an attribute?

  • The question of whether to use elements are attributes for a given data item has no easy answer;  it's pretty subjective.  But here are some basic points to consider when faced with makeing a choice:
    • 1.   Attributes are metadata (information about information) and usually represent properties of information.  They can't contain mixed content or subelements, and they don't define structure in the document.
    • 2.  Elements are data and represent components of information.  They can contain mixed content and subelements.  Elements provide both content definition and structure to the document.

Tip: Use xsl:include to share XSLT stylesheets

  • In XSLT, you can use xsl:include to share XSLT stylesheets with other XSLT stylesheets.  For example, if you have a standard transformation for XML tables that you want to globally apply to your stylesheets, you can include it in each stylesheet, like this:
    • <?xml version="1.0" encoding="utf-8"?>
    • <xsl :stylesheet
    •    smlns:xsl= version="1.0">
    • <xsl :output method="text"/>
    • <xsl :include href="tables.xsl"/>
    • ..
    • </xsl :stylesheet>
  • Make sure to insert it after the xsl:output rule if one is present.  In this example, xsl:include enables you to reuse your tables.xsl stylesheet as a modular component, instead of redefining your table transformation rules in each stylesheet.

Tip: XML declaration

  • It's always good practice to include an XML declaration at the top of an XML document.  In fact, many XML experts emphasize this, even though technically, the declaration is optional.  Of primary importance are the version and encoding attributes, especially since XML 1.1 became a recommendation.  You wouldn't expect an XML 1.0 parser to handle a 1.1 document.  Including the version in the declaration helps avoid this problem and allows the user to choose the right tool for the job.  Encoding is also important, especially if the document isn't encoded with one of the default encodings (e.g., UTF-8)
  • For example, a client sends a document with no XML declaration to a vendor.  The vendor assumes a default version/encoding of
    • <?xml version="1.0" encoding="utf-8"?>
  • But the client actually used XML 1.1 and ISO-8859-1 (latin1) to create the document, so the vendor's processes fail.  If the client had included an XML declaration of
    • <?xml version="1.1" encoding=" ISO-8859-1"?>
  • then the vendor could have either adjusted to the version and encoding or notified the client that it was incompatible with their system.  Including and XML definition identifying both the version and encoding is always beneficial.  It's a good way to make sure all parties involved are on the same page.

Tip: Recursive sections: A potential pitfall and remedy

  • A common mistake in DTDs using flexible recursive sections is to define them too loosely:
    • <!ELEMENT section     (title , (para | section)* >
  • This basically says a section can contain a title and zero or more para or section elements in any order.  The problem arises when para and sections are mixed indiscriminately:
    • <section>
    • <title>...</title>
    • <para>...</para>
    •          <section>             
    •                  <title>...</title>
    •                  <para>...</para>
    •           </section>
    •           <para>...</para>
    • </section>
  • Note that the last para follows a titled section.  In most display instances, the "hanging" para appears to be part of the nested section instead of the primary section.  There are a couple of ways to address this problem.  One is to simply instruct the editors/authors to always put standalone paras before any nested sections (and hope they comply).  Another is to define the DTD/schema more rigidly:
    • <!ELEMENT section    (title , (para* , section*) >
  • This rule says a section contains a title and zero or more paras followed by zero or more sections.  Thus, the problem is resolved; all standalone paras within a given section must precede any nested sections.  The final para in the previous example would be moved to just before the nested section.

Tip: Recursive sections: Enhanced flexibility for dynamic content

  • Recursive sections offer the flexibility to reorganize sections without retagging the content, while letting the section's position in the tree or node identify its relationship within the data/document.  For example, some DTDs/schemas use ordered sections (e.g., section1, section2, section3) to denote levels of nesting:
    • <section1>
    •         <section2>...</section2>
    •         <section2>
    •                 <section3>...</section3>
    •                 <section3>...</section3>
    •         </section2>
    • </section1>
  • If you determine that the content of one <section3> element should actually be on the <section2> level, you can't simply cut and paste the <section3> to the appropriate level; you need to rename it.  Depending on the editing system, this may require setting context rules off, moving/renaming the section, and then reparsing, or creating a new <section2>, copying the <section3> to the appropriate level; you need to rename it.   Depending on the editing system, this may require setting context rules off, moving/renaming the section, and then reparsing, or creating a new <section2>, copying the <section3>text into it, and deleting the original content.
  • This is compounded if a new general section is added to the top of the tree:  A new section1.  then, you'll need to renumber all of the succeeding sections.  However, you can eliminate these issues by defining one recursive section in the DTD:
    • <section>
    •         <section>...</section>
    •         <section>
    •                 <section>...</section>
    •                 <section>...</section>
    •         </section>
    • </section>
  • You can move sections up a level or add new section levels without causing parsing issues or requiring DTD/schema modifications.  This is especially helpful in environments where the content is dynamic or in draft form that may be reordered before they become final.

Tip: Quality assurance (QA) in an XML publishing environment

  • Ideally, in an XML publishing environment, it's a great asset to be able to split the authoring and editing staff between content/markup specialists and format specialists.  The content specialists focus on developing and tagging the data without consideration of format.  The format specialists then take that content, apply stylesheets as needed, and perform any format-related edits in the composition tool, as opposed to the data.  However, for many companies, budget constraints make it financially unfeasible to maintain two editing groups; therefore, the content editors and format editors are often the same people.  this often leads to format-specific or "creative" tagging to get a desired output for a given format creeping into the XML data itself.
  • One way to address this problem is to include an XML QA process in addition to the standard content QA.  As the last phase in the workflow before posting to the database, the QA helps avoid markup problems in the XML data set.  Each XML document passes through a markup QA specialist who first parses the data several times at different granular levels (if applicable), and then reviews the markup for anomalies or instances of creative tagging.  The QA specialist corrects minor tagging issues; more significant issues are identified and sent back to the technical writer or editor with an explanation of the problem and method for resolving it.  This gives the responsibility back to  the editors and encourages them to focus on the integrity of the content and data, rather than on formatting.

Tip: Maintaining a DTD modification history

  • A good standard practice when modifying a DTD is to document the modifications in the DTD itself.  This way you can track what changes were made, when, and by whom.  Two common ways to document DTD changes are to comment the changes within the body of the DTD next to the affected elements or to include a separate comment section to track the changes chronologically.
  • For example, you can comment a change internally, like so:
    • <!ELEMENT book (front , intro?, preface, chapter, appendix)
    • <!-- Added preface, jdoe 1-1-2004; made intro optional,
    • jsmith 7-1-2004 -->
  • The advantage to this method is that the notes are right next to the element; the disadvantage is that you have to skim the DTD to find the information you want.  An alternative is to create a modification history section, either at the beginning or the end of the DTD:
    • <!-- ********** MODIFICATION HISTORY ********** -->
    • <!-- 1-1-2004: Added preface to book element content model,
    • jdoe -->
    • <!-- 7-1-2004: Made intro optional in book element content model,
    • jsmith -->
  • The advantage of this method is that you have one chronological list detailing the changes.  It serves as a quick reference to identify changes.

Tip: Turn Internet Explorer into a handy XML/XSL debugging environment

  • By default, Internet Explorer has two drawbacks when it comes to XML debugging.  First, documents aren't automatically checked for validity, just well-formedness.  Second, when you "view source" on a transformed document, only the XML is returned--not the output from the style sheet.
  • Fortunately, Microsoft has published a simple tool kit that corrects these drawbacks and turns your Web browser into a decent debugger; it's called, appropriately, "Internet Explorer Tools for Validating XML and Viewing XSLT Output."  Once installed, you'll be able to use options on the contextual menu (i.e., the pop-up menu when you right-click in the browser window) to validate the XML document you're viewing or to see the processed XSL output.
  • You can download the tools (for free) from  After you download, double-click on iexmltls.exe to unpack the tool kit files to a directory of your choosing.  Then, go to that directory and find the files called msxmlval.inf and msxmlvw.inf.  Right-click on each of the files and choose Install.  Job done.

Tip: With XHTML, mind the MIME types

  • If you work with XHTML and you use CSS and/or JavaScript, it's important to remember the MIME type attributes of your <style></style> and <script></script> containers.  In HTML 4.0, you could get away with code like:
    • <stype>
    • p {color:red;}
    • </style>
    • <script<
    • alert("Hello!");
    • </script>
  • An XHTML parser is looking for more--specifically, it's looking for MIME types.  Here's what the validator wants:
    • <style type="text/css">
    • p {color:red;}
    • </style>
    • <script type="text/javascript">
    • alert("Hello!");
    • </script>

Tip: XHTML event handlers--no camels allowed

  • If you're making the switch from HTML to XHTML, half of your time is probably spent discovering (often by trial and error) the little differences.  Here's one gotcha that can suck up too much of your valuable time.
  • With HTML, most of us got used to "camel humping" event handlers, such as onClick, on MouseOver, and onSubmit.  If you aren't familiar with the phrase, "camel humping" refers to the notation style of capitalizing all words except the first in multi-word labels.  With XHTML--and its stubborn XML inflexibility in matters of case--your event handlers must all be in lowercase letters.
  • Here's a quick list of the basic events supported in XHMTL 1.0:
    • Keystroke events; onkeydown, onkeypress, onkeyup
    • Mouse events: ondblclick, onmousedown, onmousemove, onmouseout, onmouseover, onmouseup
    • Page and object events: onblur, onfocus, onload, onunload
    • Form events: onchange, onreset, onselect, onsubmit

Tip: Use node-set() function and exslt to calculate totals

  • For as powerful as XSLT can be, you may find yourself surprised that some trivial tasks can at first appear difficult to accomplish.  A good example of this is calculating a total price from an invoice.  In this example, we'll use the node-set() extension function to perform a total invoice calculation:
    • <?xml version="1.0" endocing=utf-8"?>
    • <Invoice>
    •    <Item>
    •       <Description>Beer</Description>
    •       <Quantity>6</Quantity>
    •       <UnitPrice>1.69</UnitPrice>
    •    </Item>
    •    <Item>
    •       <Description>Nacho Chips</Description>
    •       <Quantity>3</Quantity>
    •       <UnitPrice>0.99</UnitPrice>
    •    </Item>
    •    <Item>
    •       <Description>Salsa</Description>
    •       <Quantity>2</Quantity>
    •       <UnitPrice>1.19</UnitPrice>
    •    </Item>
    • </Invoice>
  • To solve this problem, we'll need to use extension functions, which require a separate namespace.  First, we need to declare the namespace as an extension to our stylesheet:
    • <xsl :stylesheet version="1.0"
    •    xmlns:xsl=""
    •    xmlns:exsl=""
    •    extension-element-prefixes="exsl">
  • To calculate the total price, we need to calculate the subtotals by multiplying each item price by the quantity purchased.  The variable below stores the subtotals for each item into a node list of <number> elements.  Basically, we've now assigned a result tree fragment, or "chunk" of XML code, to a variable directly:
    • <xsl :variable name="subTotals">
    •    <xsl :for-each select="//Item">
    •       <number>
    •          <xsl :value-of select="Quantity * UnitPrice"/>
    •       </number>
    •    </xsl :for-each>
    • </xsl :variable>
  • To calculate the total sum, we must add the values of each item subtotal.  The following variable adds up the sum of the subtotals using node-set function:
    • <xsl :variable name="total">
    •    <xsl :value-of select="sum(exsl :
    • node-set($subTotals)/number)"/>
    • </xsl :variable>
  • When the following stylesheet is applied to the invoice, you should see 15.489999999999998:
    • <?xml version="1.0"?>
    • <xsl :stylesheet version="1.0"
    •    xmlns :xsl=""
    •    xmlns :exsl=""
    •    extension-element-prefixes="exsl">
    •    <xsl :template match="/">
    •       <xsl :variable name="subTotals">
    •          <xsl :for-each select="//Item">
    •             <number>
    •                 <xsl :value-of select="Quantity * UnitPrice"/>
    •             </number>
    •          </xsl :for-each>
    •       </xsl :variable>
    •       <xsl :variable name="total">
    •          <xsl :value-of select="sum(exsl :node-set($subTotals)/number)"/>
    •       </xsl :variable>
    •       <xsl :value-of select="$total"/>
    •    </xsl :template>
    • </xsl :stylesheet>


Home | Company Info | Pricing | Contacts | Client Directory | Computer Tips | NewsTestimonials |
Disclaimer | Our Privacy Policy | Terms of Use | Site Map

Business Website Links, LLC 8041 Via Hacienda Palm Beach Gardens Florida 33418

Copyright 2005 all rights reserved by Business Website Links, LLC
Web Host and Design by Business Website Links, LLC