[Date Prev]
| [Thread Prev]
| [Thread Next]
| [Date Next]
--
[Date Index]
| [Thread Index]
Re: [xml-dev] Example of lousy XML design
- From: "G. Ken Holman" <gkholman@CraneSoftwrights.com>
- To: "xml-dev@lists.xml.org" <xml-dev@lists.xml.org>
- Date: Sat, 03 Aug 2013 20:35:20 -0400
At 2013-08-03 19:46 +0000, Costello, Roger L. wrote:
>Here is a sample usage:
>
> <Action> Remove </Action>
>
>That seems pretty darned straightforward. How can I possibly claim
>that it is bad XML design?
>
>Well, I do claim that. In fact, I claim that it is horrible design.
>
>Here is a typical application processing scenario for the data:
>
>Create a module for each action. My programming language is XSLT, so
>I created an XSLT template rule for each action:
>
> <xsl:template match="*" mode="Remove">
>
> <xsl:template match="*" mode="Replace">
>
> <xsl:template match="*" mode="Reject">
>
> ...
>
>Next, I read in the value of Action and stored it into a variable, $action:
>
> <xsl:variable name="action" select="//Action" />
Is there a reason that you've put the element into a variable?
>Then I fired the appropriate template, based on the value of
>$action. The way to accomplish this is with a choose statement:
>
> <xsl:choose>
> <xsl:when test="$action eq 'Remove'">
> <xsl:apply-templates select="." mode="Remove" />
> </xsl:when>
> <xsl:when test="$action eq 'Replace'">
> <xsl:apply-templates select="." mode="Replace" />
> </xsl:when>
> <xsl:when test="$action eq 'Reject'">
> <xsl:apply-templates select="." mode="Reject" />
> </xsl:when>
> ...
> </xsl:choose>
Why not:
<xsl:apply-templates select="Action"/>
<xsl:template match="Action[.='Remove']">...</xsl:template>
<xsl:template match="Action[.='Replace']">...</xsl:template>
<xsl:template match="Action[.='Reject']">...</xsl:template>
>That is awful code. It is brittle and not extensible: if new values
>for Action are added or existing values are removed, then the code
>must be changed.
To support any new functionality typically code must be
changed. Using the matching, you can have a catch-all for those not
matched, or for the choose you can have an otherwise for those not
matched. When you have a new action, add a new template rule or add
a new when to the choose.
I'm not sure where you see a problem.
>Now, however, each template rule matches one of the child *elements*
>of Action.
How is that better than matching the action with a text value? The
processor might be able to hash a template lookup quicker, but since
it is being done by the processor and not by your code with a choose,
it would probably be close enough in performance to matching an element.
>Firing the appropriate template rule requires just one statement:
>
> <xsl:apply-templates select="$action" mode="Act" />
>
>That code doesn't change even if new values for Action are added or
>existing values are removed. The code is robust and extensible.
Not sure why you say it doesn't change. It all depends on how you
coded the original stylesheet. And if the code doesn't change, then
you don't get new functionality.
But I think my match="Action[.='New']" is as acceptable as match="Action/New".
You don't say what other elements you may want in Action, but I'm
working on the premise you started with regarding comparing Action
being a text string from Action being element content.
>The redesigned XML enables the creation of applications that are
>driven by the input, i.e., "data-driven code."
>
>Lesson Learned: If an element's values will require application
>modules, one module for each value, then don't use enumeration
>lists. That is, don't design the XML like this:
>
><xs:element name="Action">
> <xs:simpleType >
> <xs:restriction base="xs:string">
> <xs:enumeration value="Remove"/>
> <xs:enumeration value="Replace"/>
> <xs:enumeration value="Reject"/>
> <xs:enumeration value="Modify"/>
> <xs:enumeration value="Alert_Management"/>
> <xs:enumeration value="Call_911"/>
> </xs:restriction>
> </xs:simpleType>
></xs:element>
>
>Instead, design the XML like this:
>
><xs:element name="Action">
> <xs:complexType >
> <xs:sequence>
> <xs:element name="Remove" type="empty" />
> <xs:element name="Replace" type="empty" />
> <xs:element name="Reject" type="empty" />
> <xs:element name="Modify" type="empty"/>
> <xs:element name="Alert_Management" type="empty" />
> <xs:element name="Call_911" type="empty" />
> </xs:sequence>
> </xs:complexType>
></xs:element>
>
>Comments?
I disagree. I think your XML should be designed based on how best
your users would understand its creation. Put the burden on the
stylesheet writer to accommodate the users ... don't make design
decisions based on complexity of implementation. One should be able
to write maintainable code for whatever the best XML is from the
user's perspective.
At least that is how I like to design my customer's
XML. Implementing it is my business ... creating it is theirs ... my
job is to make their job easy.
I don't think I've followed the arguments in your post to a
meaningful unambiguous approach or recommendation.
I hope these comments help progress your thinking on the topic.
. . . . . . . . . . Ken
--
Public XSLT, XSL-FO, and UBL classes in the Netherlands Oct 2013 |
Public XSLT, XSL-FO, UBL and code list classes in Australia Oct 2013 |
Contact us for world-wide XML consulting and instructor-led training |
Free 5-hour lecture: http://www.CraneSoftwrights.com/links/udemy.htm |
Crane Softwrights Ltd. http://www.CraneSoftwrights.com/x/ |
G. Ken Holman mailto:gkholman@CraneSoftwrights.com |
Google+ profile: https://plus.google.com/116832879756988317389/about |
Legal business disclaimers: http://www.CraneSoftwrights.com/legal |
[Date Prev]
| [Thread Prev]
| [Thread Next]
| [Date Next]
--
[Date Index]
| [Thread Index]