Difference between revisions of "Advanced LDDTool Techniques"

From The SBN Wiki
Jump to navigation Jump to search
(Update for release 0.2.0.3)
Line 15: Line 15:
 
=== What Is It? ===
 
=== What Is It? ===
  
''<code>Choice</code>'' is a mechanism that allows your label writers to use one or more of a list of attributes or subclasses at a particular point in a local class structure.  In those cases where more than one list item may be included, the items may occur in any order, and may themselves be repeated.  In other words, if I define a ''<code>choice</code>'' list containing '''A''', '''B''', and '''C''', and allow label writers to select up to three of these to include, they can include '''B''' three times, or '''C''' then '''A''' and then '''C''' again, and either case would be considered equally valid (along with all the other permutations, of course).
+
The ''<code>choice</code>'' strcuture is a mechanism that allows your label writers to use one or more of a list of attributes or subclasses at a particular point in a local class structure.  In those cases where more than one list item may be included, the items may occur in any order, and may themselves be repeated.  In other words, if I define a ''<code>choice</code>'' list containing '''A''', '''B''', and '''C''', and allow label writers to select up to three of these to include, they can include '''B''' three times, or '''C''' then '''A''' and then '''C''' again, and either case would be considered equally valid (along with all the other permutations, of course).
  
 
So, on the one hand the ''<code>choice</code>'' construct defeats some of the validation we get from using XSD, but on the other hand sometimes you can't practically code all the explicit contingencies you might have in certain scenarios.
 
So, on the one hand the ''<code>choice</code>'' construct defeats some of the validation we get from using XSD, but on the other hand sometimes you can't practically code all the explicit contingencies you might have in certain scenarios.

Revision as of 18:00, 22 January 2017

There are some advanced techniques available via the <Ingest_LDD> document and the LDDTool that might be useful in some complex cases. On the whole, SBN recommends that you resort to these only when there are compelling reasons to do so. These features are the more experimental, and thus more unstable, parts of the package.

Schematron Rules

Schematron rules can be used to check the sort of contingency relationships (i.e., "If A, then B") that XML Schema is not particularly good at. PDS also uses Schematron to define enumerated value lists rather than XML Schema largely for the diagnostic benefits - we can include the list of valid values in the Schematron error message.

Schematron rules are applied to an XML document via a two-step process involving style sheet translations (XSL). There are some subtleties to how and when Schematron rules are triggered, so if you're going to start writing Schematron rules yourself you should take some time to become familiar with the details of the standard. There are also multiple forms of the standard with a couple of significant differences in capabilities for the more advanced Schematron programmer. PDS requires ISO Schematron, which is available as a "Publicly Available Standard" (i.e., free if you promise to behave yourself) from this ISO website: http://standards.iso.org/ittf/PubliclyAvailableStandards. Search for "Schematron".

A limited capability to define additional Schematron rules as part of LDDTool processing is provided via the <DD_Rule> class. DD_Rule classes may be added after the <DD_Class> definitions in your <Ingest_LDD> document. Details for filling out the class are on the Filling Out the DD_Rule Class page.

Choice List

The XML Schema Definitions (XSD) language is very strictly ordered, but it does provide one exception to this rule: the choice construct.

What Is It?

The choice strcuture is a mechanism that allows your label writers to use one or more of a list of attributes or subclasses at a particular point in a local class structure. In those cases where more than one list item may be included, the items may occur in any order, and may themselves be repeated. In other words, if I define a choice list containing A, B, and C, and allow label writers to select up to three of these to include, they can include B three times, or C then A and then C again, and either case would be considered equally valid (along with all the other permutations, of course).

So, on the one hand the choice construct defeats some of the validation we get from using XSD, but on the other hand sometimes you can't practically code all the explicit contingencies you might have in certain scenarios.

On the whole, you should usually have some compelling reasons to resort to a choice construct in a local dictionary because of the impact on validation. "I keep getting errors from having my attributes out of order" is not a "compelling reason".

How Do I Do It?

The basic technique is to use a single <DD_Association> class to list all the possible attributes or subclasses that may be included at that point in the containing class being defined. Within that single DD_Association:

  • Repeat the <local_identifier> tag for each attribute or class you want to include in the choice list.
  • Somewhere in that list of local_identifiers, add this:
<local_identifier>XSChoice#</local_identifier>

Note that:

  • A choice list defined in this way may contain only one kind of referenced object - either all attributes or all classes, but not both in the same DD_Association.
  • The <minimum_occurrences> and <maximum_occurrences> values you provide for this DD_Association refer to the total number of selections that may be made by a label writer from the list of things corresponding to the local_identifier values.


Any Block

Any blocks are used within the shared PDS4 namespaces to pass validation control from one dictionary to another within a defined class.

What Is It?

The XSD any construct specifies that from this point until the closing tag of the current XML element, any elements from any namespace may be included and will not be subject to validation by the rules defined for the current namespace (they are required to be syntactically valid XML).

(Actually, you can also include elements from the current namespace, and they will be subject to validation as though they had occurred in their usual place in their label. This, however, is an excellent way to generate almost completely intractable error messages, and should be avoided.)


How Do I Do It?

As the last association in your <DD_Class> (yes, it absolutely must be the "last" association, since anything after an any statement in the schema is ignored with respect to the defining class definition), add one more <DD_Association> class with a <local_identifier> value of "XSAny#". The remaining attributes of DD_Class must be there, but will be ignored.

Note that:

  • If a schema validator can identify what namespaces the elements in the any area come from, and has a schema to validate them against, it will do so and report errors accordingly. So if you plan to include any blocks in your local dictionary classes, you should expect that your PDS standards reviewers will require that they only reference attributes and classes from namespaces for which PDS administers the defining schema.
  • Using the any construct abdicates control of both content and validation for that part of your mission labels. If you do not have direct and significant influence over what might be thrown into this unregulated label area, you really shouldn't be leaving this particular barn door open.


Cross-Referencing Namespace Elements

You probably shouldn't do this.

What Is It?

A namespace cross-reference invokes an attribute or class defined in another dictionary (we'll call these external elements) for use in a class that you are defining in your own dictionary. This external element will appear in labels as it appears in its own namespace, preserving its own namespace references, just interpolated into your class.

The XML technique involved is to change the namespace of reference at some local level. There are a couple different ways to do this, including changing the namespace abbreviation prefix (like "pds:" or "disp:") on the tags.

You probably shouldn't do this.

How Do I Do It?

At the point in the DD_Class definition where you want to include the external element (attribute or subclass), add a <DD_Attribute> class as you would if the element was in this dictionary, with one exception: form the <local_identifier> as "ns.name", where ns is the PDS4 reserved namespace abbreviation for the external dictionary, and name is the name of the attribute or class you want to reference as it appears in the dictionary XSD file. Note that the namespace abbreviation separator in this case is a full stop ('.'), and not the usual colon (':').

You probably shouldn't do this.

Why You Shouldn't Do This

Sometimes, in very limited circumstances, there may be compelling reasons for a mission dictionary to directly reference elements defined in other namespaces. Here's why you shouldn't ever do this in most typical mission dictionaries:

  • You have no control over changes in the referenced namespace.
  • You must assume the author of the other namespace has no knowledge of or interest in your cross-reference.
  • You must assume there is no commitment on the part of the author of the other namespace to maintain his elements in a way that will not invalidate your cross-reference, technically or informationally.
  • You are requiring end-users to go outside your own dictionary to understand classes defined in your dictionary.

Even references to discipline dictionaries and the PDS core namespace are problematic at this early stage of release, with the ongoing development cycles. If you really think you need to pull in elements from dictionaries you do not control, talk to your PDS node consultant first.

And then don't do it.

If, however, you find yourself managing a large mission in which teams or instruments are each creating their own dictionaries, in addition to the overarching mission dictionary, then you might have both good reasons and sufficient control to reasonably reference, say, the mission dictionary from the instrument dictionaries, or conversely.

More Reasons Why You Shouldn't Do This

This is an extremely experimental capability that has not been nearly fleshed out as yet. In particular, note that:

  • The namespace abbreviation in itself is not sufficient to identify a namespace, and even within the reserved PDS4 namespace abbreviations, it carries no information about versioning. All versions of a namespace have the same reserved abbreviation.
  • If you write and validate your dictionary based on assumptions related to a particular version of the namespace you're referencing, you have no way at present to prevent erroneous linking to a different and potentially incompatible version of the same external namespace in labels. Worse, the labels may attempt to reference two different versions of the same namespace. At best, this generates validation warnings that may or may not be safely ignored. At worst, validation will be completely and wordlessly undermined as the software environment decides which version of the namespace should apply.
  • As there is no requirement in your own dictionary that every attribute or class have a unique <name>, there is no requirement in any other dictionary that attributes and classes have unique names. On top of that, the local_identifier values are not carried into the XSD version of the dictionary file to help distinguish between elements in different contexts that have the same name. So unless you know that the external element you are referencing a) has a unique name; and b) will always have a unique name, cross-referencing it by that non-unique handle is fraught with peril.

Even More Reasons Why You Shouldn't Do This

  • LDDTool decides which version of the core dictionary or a discipline dictionary it will pull its definitions from - you cannot alter that. And which version it will reference depends on what is programmed into the specific version of the LDDTool you're using. This may not be the same version of the discipline dictionary referenced directly in labels for other reasons. In fact, if you've updated your version of LDDTool, it might not even be the same version that was referenced last time you ran the tool.
  • The classes you reference are only available to be referenced by type - so the name of the class is in your dictionary's namespace, but the attributes are in the original namespace. This effectively prevents any Schematron rules that might enforce things like standard values or attribute content from recognizing the class as something it should be validating. So you can include the Display dictionary Display_Direction class as a subclass of one of your local classes, but the name <Display_Direction> will be in your own dictionary namespace while the attributes like horizontal_display_direction will still be in the disp: namespace. This will prevent the Display schematron file from checking that the value of horizontal_dislay_direction is either "Left to Right" or "Right to Left", because the schematron file only recognizes <disp:Display_Direction>, i.e., the class in the original Display namespace.