tag:blogger.com,1999:blog-35444443950564910262024-03-14T11:45:22.162-07:00The S1000D DeveloperEWHhttp://www.blogger.com/profile/17985891579499891276noreply@blogger.comBlogger7125tag:blogger.com,1999:blog-3544444395056491026.post-69606211706087439612015-12-03T15:39:00.000-08:002015-12-03T15:42:48.049-08:00How to write BREX context rules (part 3): Learning by Example<p>In part 3 of "<em><a
href="/2015/11/how-to-write-brex-context-rules-part-1.html">How
to write BREX context rules</a></em>," the
<code><structureObjectRule></code> element is introduced: the
element for defining a <em>structure object rule</em> using XPath. If
you are not familiar with XPath, you can review <a
href="/2015/11/how-to-write-brex-context-rules-part-2.html">
How to write BREX context rules (part 2): XPath Primer</a>. </p>
<p>Since the S1000D specifications provides the element and attribute
breakdown of the <code><structureObjectRule></code> element (Chap
4.10.2.2, Para 2.1.1 of Issue 4.1), an example-based approach will be
used in learning how to write structured rules.
</p>
<h3>Example Rule 1: All procedural steps must have an ID</h3>
<p>For our first example, the following business rule has been decided
upon:
</p>
<blockquote>
<em>All procedural steps must have an authored ID.</em>
</blockquote>
<p>For the purposes of this
post, we are not really concerned about the reason for this rule. But
if you are curious why a project may have such a rule, and where a
project can document the reasons behind a rule, see my post,
<a
href="/2015/11/what-is-difference-between-brdoc-and.html">What
is the difference between brDoc and BREX?</a>
</p>
<h4>Attempt 1</h4>
<p>At inital glance, writing the structured rule for this decision
seems straight-forward, so here is our first try at writing the rule:
</p>
<dl><dt><em>Note:</em></dt>
<dd>The following is not how the rule should be written.
I will explain later on how this illustrates a mistake
a beginning BREX rule author may make.</dd>
</dl>
<pre>
1: <structureObjectRule>
2: <b><objectPath allowedObjectFlag="1">//proceduralStep[@id]</objectPath></b>
3: <objectUse>A procedural step must have an authored ID.</objectUse>
4: </structureObjectRule>
</pre>
<p>I will describe each line of the rule:
</p>
<dl>
<dt>Line 1</dt>
<dd><p>The start tag: The rule itself is defined by child elements.
</p>
</dd>
<dt>Line 2</dt>
<dd><p><code><objectPath></code>
specifies the actual XPath expression and how that expression is
applied via the <code>allowedObjectFlag</code> attribute. When
<code>allowedObjectFlag</code> is "<code>1</code>", it indicates
that the object identified by the XPath expression is required
and must exist in the data.
</p>
<p>The XPath expression is the textual content of
the <code><objectPath></code> element, with the
given expression matching any <code><proceduralStep></code>
element in a data module that has an ID.
</p>
</dd>
<dt>Line 3</dt>
<dd><p>The <code><objectUse></code> element provides a
human-readable description of the rule. It is highly likely that
your IETP authors are not well-versed in XPath expressions, so it
is important that you provide a human-readable description of the
rule.
</p>
</dd>
<dt>Line 4</dt>
<dd><p>The end tag.
</p>
</dd>
</dl>
<h4>Problem with Attempt 1</h4>
<p>Attempt 1 is based on a misunderstanding of the
<code>allowedObjectFlag</code> attribute. The attribute applies to
the entire expression, so when it has a value of "<code>1</code>", the
expression <b>must always</b> evaluate to a <em>true</em> condition.
</p>
<p><em>What does that mean for the rule we created?</em></p>
<p>Any data module we validate against the rule will fail if the DM does
not have a <code><proceduralStep></code> with an <code>id</code>
attribute. Therefore, all non-procedural DMs will always fail
validation. We either need a way to restrict the rule to apply
to procedural DMs only, or a rule that allows us to satisfy the business
rule requirement without causing false failures.
</p>
<h4>Attempt 2: Context-specific rule</h4>
<p>As mentioned in <a
href="/2015/11/how-to-write-brex-context-rules-part-1.html">Part
1</a>, rules can be contextualized by schema type (but make note in
Part 1 of the deficiencies of using context-specific rules).
Using this capability, we can have the following: </p>
<pre>
1: <contextRules
2: <b>rulesContext="http://www.s1000d.org/S1000D_4-1/xml_schema_flat/proced.xsd"></b>
3: <structureObjectRuleGroup>
4: <structureObjectRule>
5: <objectPath allowedObjectFlag="1">//proceduralStep[@id]</objectPath>
6: <objectUse>A procedural step must have an authored ID.</objectUse>
7: </structureObjectRule>
8: </structureObjectRuleGroup>
9: </contextRules>
</pre>
<p>This addresses the problem of the rule being applied to
non-procedural data modules. However, it still fails to adequately
enforce the busines rule.
</p>
<h4>Problem with Attempt 2</h4>
<p>The rule in Attempt 2 will evaluate to true if there is at least one
<code><proceduralStep></code> with an <code>id</code> attribute.
If a data module has other steps, but no <code>id</code> is present,
the rule will still pass as long as the expression matches at least
one node.</p>
<p>The business rule requires that <b>all</b> steps have an ID. So we
need a way to verify that every <code><proceduralStep></code>
instance in a DM has an <code>id</code> attribute.
</p>
<h4>Attempt 3: Match what is not allowed</h4>
<p>When it comes to writing structured rules, you will realize the
following guiding principle will making writing rules much easier:
</p>
<blockquote>
<em>It is generally easier to match what is not allowed vs what is allowed.</em>
</blockquote>
<p>Or, in geek-speak:</p>
<blockquote>
<em>Applying inverse logic to a business rule can result in a simplier
structured object rule.</em>
</blockquote>
<p>As a BREX rules developer, when I read the following business rule,
"<em>All procedural steps must have an authored ID</em>," I
immediately apply inverse logic and translate it to the following,
equivalent statement,
"<em>Procedural steps with no authored ID are not allowed</em>."
</p>
<p>With the inverse rule, the BREX rule can be expressed as follows:
</p>
<pre>
1: <structureObjectRule>
2: <b><objectPath allowedObjectFlag="0">//proceduralStep[not(@id)]</objectPath></b>
3: <objectUse>A procedural step must have an authored ID.</objectUse>
4: </structureObjectRule>
</pre>
<p>The markup is very much like our first attempt, but with the
following key changes:
</p>
<ul>
<li><p>The <code>allowedObjectFlag</code> value is set to
"<code>0</code>". "<code>0</code>" indicates that any object matched by the
expression is not allowed. If a data module contains content that
matches a rule with an <code>allowedObjectFlag</code> of
"<code>0</code>", the DM
will fail validation.</p>
<li><p>The XPath expression has been modifed to match nodes that
should not be present, in this case, steps with no ID attribute.
</p>
</li>
</ul>
<p>It is worth noting that the <code><objectUse></code> text is
left unchanged. Inverse statements may make writing BREX rules
easier, but are not necessarily easier for IETP authors to understand.
An inverse rule tends to utilize negation, which can be harder to
comprehend. For example, which of the following equivalent business
rules do you think most people will understand easier: </p>
<blockquote>
<em>All procedural steps must have an authored ID.</em>
</blockquote>
Or,
<blockquote>
<em>Procedural steps with no authored ID are not allowed.</em>
</blockquote>
<p>?</p>
<h4>Problems with Attempt 3</h4>
<p>There are no problems! The rule addresses the following deficiencies
of previous attempts:
</p>
<ul>
<li>Non-procedural DMs are unaffected by the rule since they will
never match an expression containing
<code><proceduralStep></code> (a problem with attempt 1).
</li>
<li>With inverse logic, we know a single step with an ID cannot
mask steps without IDs (a problem with attempt 2).
</li>
</ul>
EWHhttp://www.blogger.com/profile/17985891579499891276noreply@blogger.com0tag:blogger.com,1999:blog-3544444395056491026.post-54529958814723140692015-11-24T09:59:00.000-08:002015-12-03T15:43:03.038-08:00How to write BREX context rules (part 2): XPath Primer<p>In <a
href="http://www.s1000d-developer.com/2015/11/how-to-write-brex-context-rules-part-1.html">Part
1</a>, I provided a basic introduction to writing BREX context rules and
the <code><contextRules></code> element. In the second part of
this series, I will provide a brief primer to XPath expressions.
A complete guide to writing XPath expressions is beyond the scope
of this post, but you will need a basic understanding of XPath to
get started in writing structured rules for your project.
After reading this post, I recommended reviewing any of the numerous
XPath tutorials on the web.
</p>
<h3>What is XPath?</h3>
<p>XPath provides a syntax for identifying parts (formally known as
<em>nodes</em>) of an XML document.
An XML document intrinsically defines a tree structure, similar to how
files on a file system are organized. For example,
see how the location of the folder "<code>program</code>" is
identified at the top of Windows file explorer:
</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwa_6ZJ_a2bHzkoIV5wzxise0jZDzAmI2rls5YiBDNlWA7IIc_BfxE1b-M0m4CO8mjGJL2TXuZoN83KoWkht5xUrk8FiJo-Lb1Fb5WSY-IBiEEMpDgWVNIKA12PBcUqk2jGGLwmYmAoE9s/s1600/file-explorer-pathname.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwa_6ZJ_a2bHzkoIV5wzxise0jZDzAmI2rls5YiBDNlWA7IIc_BfxE1b-M0m4CO8mjGJL2TXuZoN83KoWkht5xUrk8FiJo-Lb1Fb5WSY-IBiEEMpDgWVNIKA12PBcUqk2jGGLwmYmAoE9s/s320/file-explorer-pathname.png" /></a></div>
<p>The absolute location is
"<code>C:\Program Files\LibreOffice 5\program"</code>.
With XPath, we identify XML elements in a similar manner, but
we use forward slashes, "<code>/</code>", instead of backslashes.
For example, say we have the following XML document structure:
</p>
<pre>
<dmodule>
<content>
<b><brex></b> <!-- We want to identify this element here -->
...
</content>
</dmodule>
</pre>
<p>We can identify the <code><brex></code> element with the
following XPath expression:
</p>
<pre>/dmodule/content/brex</pre>
<p>Unlike a file system, an XML document can have the items of
the same name at the same level. For example:
</p>
<pre>
<dmodule>
<content>
<brex>
<contextRules>
<structureObjectRuleGroup>
<b><structureObjectRule></b>... <-- We want this one -->
<structureObjectRule>... <-- Not this one >
...
</structureObjectRuleGroup>
</contextRules>
</brex>
</content>
</dmodule>
</pre>
<p>If we use the XPath expression,
<pre>/dmodule/content/brex/contextRules/structureObjectRuleGroup/structureObjectRule</pre>
<p>we are actually identifying all
<code><structureObjectRule></code> elements under
<code><structureObjectRuleGroup></code>. If we only want the
first <code><structureObjectRule></code> element, we do the
following:
<pre>/dmodule/content/brex/contextRules/structureObjectRuleGroup/
structureObjectRule<b>[1]</b></pre>
<p>Technically, we may still identify more than one
<code><structureObjectRule></code> element.
If you are familiar with the BREX schema—note, this applies to any
XML document, just using BREX type as an example—
<code><contextRules></code> and
<code><structureObjectRuleGroup></code> are repeatable. So
if we take,
<pre>/dmodule/content/brex/contextRules/structureObjectRuleGroup/
structureObjectRule[1]</pre>
<p>and apply it to the following XML document:
</p>
<pre>
<dmodule>
<content>
<brex>
<contextRules>
<structureObjectRuleGroup>
<b><structureObjectRule></b>... <-- MATCH -->
...
</structureObjectRuleGroup>
</contextRules>
<contextRules>
<structureObjectRuleGroup>
<b><structureObjectRule></b>... <-- MATCH -->
...
</structureObjectRuleGroup>
</contextRules>
</brex>
</content>
</dmodule>
</pre>
<p>We will have identified two
<code><structureObjectRule></code> elements. If we want to only
identify the very first <code><structureObjectRule></code> element
in the document, we use the following:
</p>
<pre>/dmodule/content/brex/contextRules<b>[1]</b>/
structureObjectRuleGroup<b>[1]</b>/structureObjectRule[1]</pre>
<h3>Identifying by ID</h3>
<p>If your XML documents contain IDs, using them to identify elements is
much easier than using full paths. Take the following for example:
</p>
<pre>
<dmodule>
<content>
<brex>
<contextRules>
<structureObjectRuleGroup>
<b><structureObjectRule id="SOR-001"></b>... <-- We want this one -->
<structureObjectRule>...
...
</structureObjectRuleGroup>
</contextRules>
</brex>
</content>
</dmodule>
</pre>
<p>The element we want to identify can be expressed as follows:
</p>
<pre>//structureObjectRule[@id="SOR-001"]</pre>
<p>The expression contains some components that need further
explanation:
</p>
<dl>
<dt><b><code>//</code></b></dt>
<dd><p>This is a shorthand notation indicate any decendant node.
Since it is at the start of the expression, it indicates any
node within the document.
</p>
</dd>
<dt><b><code>[@id="SOR-001"]</code></b></dt>
<dd><p>The "<code>[]</code>" represents a conditional expression
on the node that precedes it. In this case, the node that
proceeds it is <code>structureObjectRule</code>. In order
for a <code>structureObjectRule</code> to match the expression,
the expression inside the <code>[]</code>'s must evaluate to a
true value.
</p>
<p>In our example, the conditional expression,</p>
<pre>@id="SOR-001"</pre>
<p>is only true if the attribute named "<code>id</code>" has the
value "<code>SOR-001</code>". In XPath, to distinguish an element
name from an attribute name, attribute names are prefixed with the
'<code>@</code> character, hence the use of "<code>@id</code>".
If we left out the '<code>@</code>', the name "<code>id</code>"
would have been interpreted as the name of a child element.
</p>
</dd>
</dl>
<h3>Identifying by any attribute</h3>
<p>You are not limited to ID attributes for identifying elements in an
XML document. For example, if I wanted to identify all elements marked
as deleted, I can use the following:
</p>
<pre>//*[@changeType="delete"]</pre>
<p>The special character "<code>*</code>" will match any element, but
the attribute test condition limits the matching to only those elements
that have the <code>changeType</code> set to "<code>delete</code>".
</p>
<h3>More Information</h3>
<p>More complete tutorials on XPath can be found by <a
href="https://www.google.com/search?q=xpath+tutorial&ie=utf-8&oe=utf-8">searching
the web</a>. </p>
<h3>Next</h3>
<p>
<a
href="/2015/12/how-to-write-brex-context-rules-part-3.html">Learning by Example</a>
</p>EWHhttp://www.blogger.com/profile/17985891579499891276noreply@blogger.com0tag:blogger.com,1999:blog-3544444395056491026.post-36753610053958439962015-11-16T22:04:00.000-08:002015-12-03T15:43:14.791-08:00How to write BREX context rules (part 1)<p>
This is the first in a I-do-not-know-how-many posts on how to write
BREX context rules. Hopefully, I can provide guidance on what some
may consider the voodoo magic of writing context rules, and show
that you do not have to be an
<a href="http://www.w3.org/TR/xpath20/">XPath</a>
wizard to write effective context rules.
</p>
<p>
BREX context rules provide the ability to precisely
define what structures are allowed and not allowed in your project's
data. This is achieved by using <a
href="http://www.w3.org/TR/xpath20/">XPath</a> expressions.
XPath expressions can get quite complex, but in the majority of the
cases, you only need to utilize a basic subset of XPath.
</p>
<p>A key benefit to context rules is they can be validated in
an automated fashion with the use of a BREX validation tool
(aka <em>BREX checker</em>).
Therefore, if you have a business rule that is applicable to the XML
structure of your data, it is best to express it as a context rule
to minimize the need for manual verification of the rule.
</p>
<h3>The <code><contextRules></code> element</h3>
<p>In a BREX data module, context rules are specifed under the
<code><contextRules></code> element:
</p>
<pre>
<dmodule>
<content>
<brex>
<b><contextRules></b>
...
<b></contextRules></b>
</brex>
</content>
</dmodule>
</pre>
<p>The <code><contextRules></code> element is repeatable.
As the element name implies, you can specify a specific context for set
of rules. For example, if you have a set rules that are only applicable
for procedural data modules and another set of rules only applicable
for fault data modules, you can have the following:
</p>
<pre>
<contextRules
<b>rulesContext="http://www.s1000d.org/S1000D_4-1/xml_schema_flat/proced.xsd"</b>>
...
</contextRules>
<contextRules
<b>rulesContext="http://www.s1000d.org/S1000D_4-1/xml_schema_flat/fault.xsd"</b>>
...
</contextRules>
</pre>
<p>The <code>rulesContext</code> attribute value <b>must</b> be a schema
URI. BREX checkers examine the value to determine when the set of
rules should be verified against a data module.
</p>
<p>When the <code>rulesContext</code> attribute is not specified, then
then rules apply to all S1000D CSDB object types:
</p>
<pre>
<contextRules>
<!-- rules for all object types -->
</contextRules>
</pre>
<h3>Limitations of the <code>rulesContext</code> attribute</h3>
<p>Unfortunately, the <code>rulesContext</code> is very limited, and
can be impractical to use. Reasons:
</p>
<ul>
<li><p>A data module's schema URI must match exactly the schema URI
specified in the <code>rulesContext</code> attribute for the rules
to be applied. If you have been a good IETP author and have
been using the standard schema URIs, this is not a problem.
However, I have encountered data where schema URIs refer to local
pathnames (e.g. "<code>file://C:/data/...</code>") (apparently
there are still folks that do not utilize
<a href="https://en.wikipedia.org/wiki/XML_Catalog">XML
Catalogs</a>).
</p>
</li>
<li><p>Only a single URI can be specified in the
<code>rulesContext</code> attribute. This can be very limiting if
you have rules that may be applicable to more than one schema
type, or applicable to different issues of a given schema type.
For example, if you have a rule that is applicable to procedural and
fault data modules, you would need to list that same rule twice,
once for the procedural context and once for the fault context.
</p>
<p>Another case is if you have a publication with mixed-Issue data
modules (e.g. 4.0, 4.0.2, 4.1, 4.1.A, etc) and you have rules that
are applicable to both.
</p>
</li>
</ul>
<p><em>Note:</em> I have considered submitting a CPF to allow for
multiple schema URIs to be specified for <code>rulesContext</code>.
Since no one else has bothered to submit one in all this time, it is
likely the attribute is rarely used (or used in very limited contexts)
since it is more common to define XPath expressions to include
whatever context is needed (see below).
</p>
<h3>Alternative to the <code>rulesContext</code> attribute</h3>
<p>IMO, the limitations of <code>rulesContext</code> are pretty severe.
Fortunately, with the use of XPath, we can achieve context-based rules
without the need of using the <code>rulesContext</code> attribute.
I will go into more depth on how to write structure object
rules in a future post, but the following should give you a basic idea
of how a rule can be
constructed so it only applies to a data module of a given type:
</p>
<pre>
<structureObjectRule>
<objectPath allowedObjectFlag="0"><b>/dmodule/content/
illustratedPartsCatalog</b>//partNumber[not(@id)]</objectPath>
<objectUse>Part numbers in IPDs must have an authored ID.</objectUse>
</structureObjectRule>
</pre>
<p>The rule in the example is somewhat bogus, but it illustrates how I
was able to contextualize the rule to only IPDs by leveraging the XML
schema structure of IPDs. Here is a brief explanation of the
expression:
</p>
<ul>
<li><p>The start of the expression,
"<code>/dmodule/content/illustratedPartsCatalog</code>" restricts
any matches to under the <code><illustratedPartsCatalog></code>
element. Since no other
schema type allows such a structure, I have effectively limited the
application of the rule to IPDs.
</p>
</li>
<li><p>The next part is the expression
"<code>//partNumber</code>", which indicates any
<code><partNumber></code> elements under
<code><illustratedPartsCatalog></code>, at any depth.
The XPath expression "<code>//</code>" indicates descendants
of any depth.
</p>
</li>
<li><p>The "<code>[not(@id)]</code>" says to only match
<code><partNumber></code> elements with no <code>id</code>
attribute.
</p>
</li>
</ul>
<p>With the designation of <code>allowedObjectFlag="0"</code> for the
rule, any match of the above expression is not allowed. Therefore,
if the expression does match a node in a data module, that DM will
not pass validation.
</p>
<h4>Equivalent <code>rulesContext</code>-based rule</h4>
<p>An equivalent rule that relies on the use of
<code><contextRules></code>'s <code>ruleContext</code>
attribute would be the following:
</p>
<pre>
<contextRules
<b>rulesContext="http://www.s1000d.org/S1000D_4-1/xml_schema_flat/ipd.xsd"</b>>
<structureObjectRuleGroup>
<structureObjectRule>
<objectPath allowedObjectFlag="0"><b>//partNumber[not(@id)]</b></objectPath>
<objectUse>Part numbers in IPDs must have an authored ID.</objectUse>
</structureObjectRule>
</structureObjectRuleGroup>
</contextRules>
</pre>
<p>Notice how the XPath expression is briefer since I no longer have
to establish a context within the expression itself. With the
<code>ruleContext</code> attribute setting, I know that the rule will
only be evaluated on Issue 4.1 IPD data modules.
</p>
<p>You may be satisfied with using the <code>ruleContext</code> version if
you know all your data modules will use well defined schema URIs and
you have little to no occurrances of rules that are applicable to
multiple schema types.
However, IMO, it is better practice to author rules that are less
susceptible to external changes that could make the rule "stale",
especially when the staleness may go unnoticed. For example, if
you change the schema URIs of your modules, the existing rules will
no longer be applied by the BREX checker. This can go unnoticed,
leading to potential false validation passes of data.
</p>
<h3>Next</h3>
<p>
<a
href="/2015/11/how-to-write-brex-context-rules-part-2.html">XPath Primer</a>
</p>
EWHhttp://www.blogger.com/profile/17985891579499891276noreply@blogger.com0tag:blogger.com,1999:blog-3544444395056491026.post-42351325399731031232015-11-09T12:29:00.000-08:002015-11-09T16:12:53.086-08:00What is the difference between brDoc and BREX?<p>At the 2015 S1000D User Forum, information was provided about the new
schema type, <code>brDoc</code>, coming to Issue 4.2. One of the
audience member asked what is the difference between <code>brDoc</code>
and the BREX. I thought the answer the presenter gave was not very
clear. I do not recall specifically what the presenter said, but I
could tell the audience member was still confused.
</p>
<p>During a break, I approached the audience member and said something
like the following:
</p>
<blockquote>
<code>brDoc</code> explains the "<em>Why</em>" of your business rules
while the BREX provides the "<em>How</em>".
</blockquote>
<p>The BREX DM mainly lists out the rules your data was authored
against, but may not provide the reasoning behind the decisions made
in establishing the rule. For example, you may have a BREX rule
stating, "All procedural steps must have an authored ID," which
can be codified in a <code><structureObjectRule></code>.
The <code>brDoc</code> DM would provide the reasons the rule exists,
which may be due to cross-referencing requirements for the project.
</p>
<p>In Issue 4.2, the BREX schema has been updated so for a given rule,
you can reference back to the <code>brDoc</code> data module that provides
reasoning behind the rule. This linking is done with
<em>BR decision identifiers</em>, which are specified in the
<code>brDoc</code> data module via <code><brDecision></code> nodes.
In the BREX, you reference the identifiers via
<code><brDecisionRef></code> nodes.
</p>
<p>For example, in the <code>brDoc</code> DM, you may have something
like the following:</p>
<pre>...
<brDecision brDecisionIdentNumber="MYPROJ-BRD-00001">
...
<brDecisionExplanation>
<para>Identifiers on procedural steps are required so specific
steps can easily be identified in the viewing system when
the maintainer submits a problem report on a procedure and/or
specific steps of a procedure. </para>
</brDecisionExplanation>
</brDecision>
...</pre>
<p>And in your BREX, you have something like the following to refer
back to the decision documented in the <code>brDoc</code> data module:
</p>
<pre>...
<structureObjectRule...>
<brDecisionref brDecisionIdentNumber="MYPROJ-BRD-00001"/>
<objectPath allowedObjectFlag="0">//proceduralStep[not(@id)]</objectPath>
<objectUse>All procedural steps must have an authored ID.</objectUse>
</structureObjectRule>
...</pre>
EWHhttp://www.blogger.com/profile/17985891579499891276noreply@blogger.com0tag:blogger.com,1999:blog-3544444395056491026.post-44543252303917213622015-11-06T00:57:00.000-08:002015-11-06T00:58:15.172-08:00How not to use applicability<p>While attending the S1000D User Forum (UF), I sat in on the following
presentation, <a href="http://public.s1000d.org/Documents/2015%20S1000D%20User%20Forum%20presentations/Wed%20Track%20A%201130%20Cook%20Creating%20Applicability%20Statements%20that%20Work!.pdf">Creating Applicability Statements that Work for the CCT</a>.</p>
<p>I <b>highly recommend</b> to <b>not</b> following the guidance in this UF
presentation regarding service bulletins:</p>
<ul>
<li><p>It is mixing technical data with product configuration.
The ACT's and CCT's roles are to provide the <b><i>definitions</i></b> of
your product attributes and conditions. The PCT is designed to contain
the actual instances of those attributes. Take the English dictionary
as an analogy. The dictionary provides the definitions of the words.
The actual instances of those words are in separate books, essays, and
other English-based writings.
What the UF presentation is advocating that for specific, special words, we
should include all the various writings that use those words in the
dictionary itself.
</p>
<p>The PCT is the only module type designed to capture product
configuration. It exists to complete the XML-based model of
applicability, but in practice, the PCT either is not used (it's use
is optional), is stubbed just to contain the primary keys (to
faciliate product selection in a viewer), or is dynamically generated
from the product configuration database, not the CSDB.
</p>
<p>For example, for NAVAIR, we have one program that only stores
aircraft identifiers in the PCT (called "BUNOs"). When the viewer
is launched, the configuration database is queried for the current
state of all the other attributes, including service bulletins
(NAVAIR calls them Tech Directives)
and passes the values to the viewer to initialize applicability state table.</p>
</li>
<li><p>PCT-based filtering does <b>NOT</b> require you to assert against
the primary product key everytime. This is a strawman the UF
presentation argues to justify the model it is advocating. When authoring applicability, you
only need to assert on those attributes that are relevant. For
example, if a given procedural step is only applicable if a given
service bulleting is incorporated, all you need to do is the
following:</p>
<pre><applic id="a001">
<assert applicPropertyIdent="SB-001"
applicPropertyType="condition" applicPropertyValues="PRE"/>
</applic></pre>
<p>There is nothing that requires you to always have assertion against
the product key. If a step is only dependent on certain conditions,
you only need to assert against those conditions. Only assert on
the entire product if a step is only applicable for entire
product instances.
</p>
<p>When maintenance is started, normally the product being worked
on would have been selected at the start of maintenance. Therefore,
all the production configuration attributes and conditions
(represented in the PCT--either statically or dynamically--see above),
will have been set into the state table, including the incorporation
status of SB-001 for the product.
</p>
</li>
<li><p>The UF presentation increases the complexity of the viewing
system in assigning values into the state table.
Instead of just reading all the attribute values from the selected
product from the PCT, the viewer now has to parse the
<incorporation> section of the CCT, follow several
extra ID references, and apply
applicability filtering to determine SB values. This introduces
unnecessary complexity in the
viewing implementation when the same effect can be achieved
with the simplier PCT-based model.
</p></li>
<li><p>If you make the assumption that UF presentation regarding
service bulletins is the better model, then why not use the model for
all attributes? From a data modeling perspective, there is nothing
special about service bulletin incorporation state that justifies
it being handled differently than any other property (product
attribute and/or condition) associated with a
product. The UF presentation is basically advocating that for these
set of properties, use a complicated way to assign their values,
but for all other properties, assign them in the PCT.
</p></li>
</ul>
<p>The danger of that UF presentation is the presenter was very animated
that this <b>is</b> the way you should do service bulletins, and for
those in the audience that were new to S1000D, and less knowledgable of
how applicability works, they can be lead down an operational path that
is more complex and more expensive. Because of this, I voiced
my concerns during the Q&A period.</p>
<p>Afterwards, I had a
gentlemen come to me and thank me I did say something. He was fairly new
to S1000D, and right after the presentation, he worried that the way they
were going to use applicability was wrong, because a supposed expert was
vocal in saying what was the right way and what was the wrong way.
After I voiced my objections, he felt much better that he and his
program made valid choices on how to use applicability.
</p>
<p>Sometime later, I was informed this service bulletin applicability
model was pushed for by Civil Aviation, hence, changes to the S1000D
specification to support it. The push for the change came from
a large aircraft provider to reflect how they
managed their techdata and product configuration over the years. So,
instead of the company changing their operations to use a better model,
they basically pushed in changes into S1000D so they can continue as
business as usual and state they are S1000D conformant. </p>
EWHhttp://www.blogger.com/profile/17985891579499891276noreply@blogger.com2tag:blogger.com,1999:blog-3544444395056491026.post-8481868866838736332015-11-05T22:09:00.001-08:002015-11-05T22:09:46.340-08:00Issue 4.1 Applicability<p>My colleague did an admirable job in providing a presentation on Issue 4.1 Applicability at the S1000D User Forum in San Diego. The presentation is available from the <a href="http://public.s1000d.org/Documents/2015%20S1000D%20User%20Forum%20presentations/Wed%20Track%20A%201030%20McCarthy%20UserForum-Applicability.pdf">s1000d.org site</a>.</p>
<p>We got the idea of doing the presentation during our work in updating NSIV, an S1000D viewer, to support the applicability features in Issue 4.1. Although Issue 4.1 has been published for some time now, we encountered problems in the specification related to 4.1 applicability, which could lead to author confusion and ambiguous implementations of the model.</p>
<p>One thing we unfortunately left out of the presentation was the new externalized applicability capability. Applicability annotations can now be stored in a CIR (<i>common information repository</i>) DM (<i>data module</i>) where they can be referenced in other DMs. With only 30 minutes provided for the presentation, it was hard enough to squeeze the material that was included in the time allotted.</p>
<p>Along with the creation of the presentation for the user forum, we submitted several CPFs (<i>Change Proposal Forms</i>) through the <a href="http://s1000d.us/">USSMG</a> to "clean up" the new features of the 4.1 applicability model. It was too late to see any changes incorporated into the upcoming Issue 4.2 release, but we hope our proposed changes will be incorporated in the release after that.</p>
<p>I am interested in finding out who else has implemented the 4.1 applicability model in their S1000D processing and rendering tools. I have doubts that those using any 4.1 features have software that supports the entire model. If others have implemented a complete model, I would have expected CPFs to have already been submitting to address the problems I encountered during my fairly complete implementation of the 4.1 model.</p>
<p>The applicability related CPFs my colleage and I have submitted are as follows:</p>
<ul>
<li>Clarification is needed on Filtering Rules for External references vs Alias attributes</li>
<li>Clarification is needed regarding a ‘non string’ type product and/or condition attribute – that it may provide an enumeration label. In addition, there currently is no way to ensure applicability property values conform to its data-typing</li>
<li>Formal definitions are needed for applicability attribute value types: Boolean, Integer, and Real.</li>
<li>Clarification is needed on the use of external reference applicability attributes and alias attributes within the Applicability cross-reference table catalog.</li>
<li>If a Pub Module or Data Module contains a computable branch of an applicability annotation, it must also include a reference to the Applicability Cross-reference Table (ACT) data module <applicCrossRefTableRef>.</li>
<li>Clarification is needed on the fact that multiple associations can be made for alias attributes, but only one can be made for external attributes.</li>
<li>There is a conflict between chapter text and the schema. The element “Applicability Reference” <applicRef> supports externalized applicability annotations. Specification text identifies its child element <dmRef> as mandatory, yet schema has as optional.</li>
<li>Clarification is needed on the defining of a product or condition attribute marked as an alias.</li>
</ul>
EWHhttp://www.blogger.com/profile/17985891579499891276noreply@blogger.com0tag:blogger.com,1999:blog-3544444395056491026.post-48549407408372016942015-11-05T21:12:00.000-08:002015-11-05T21:12:05.227-08:00First Post<p>This blog is an attempt to capture my experiences of working with <a href="http://www.s1000d.org/">S1000D</a>, primarily from the perspective of a software developer. In my 20+ years in developing software, the past 7 years has mostly been dealing with S1000D and the development of an <i>Interactive Electronic Technical Publication</i> (IETP) viewer supporting publications authored in S1000D. The viewer is called NSIV, which currently stands for NAVAIR Standard IETM Viewer.
The use of "IETM" is an older term still used by NAVAIR that stands for <i>Interactive Electronic Technical Manual</i>.</p>
<p>During my time working on the viewer, I have also been involved with the development of the S1000D specifications itself by attending and participating in various working group meetings. My current areas of expertise are the <i>S1000D applicability model</i> and <i>BREX</i> (Business Rules Exchange). I have implemented the applicability model in NSIV and developed a BREX validation tool for NAVAIR.</p>
<p>One thing I have noticed during my observations and participation in the evolution of the S1000D specification is an inadequate representation of individuals with direct, on-hands experience in developing S1000D-aware software tools. Yes, there are folks from companies that have developed S1000D software, but those representatives tend to me more on the data-side and not directly involved in the software side. This deficiency ends up getting reflected in the specification. I will likely expand more on this is later posts.</p>
EWHhttp://www.blogger.com/profile/17985891579499891276noreply@blogger.com1