obdurodon / dh_course

Digital Humanities course site
GNU General Public License v3.0
20 stars 6 forks source link

Carving an XPath through Schematron #452

Closed dap167 closed 3 years ago

dap167 commented 4 years ago

For the assignment due on the 26th, you might be stumped a little by some of the things we need to do. For example, no duplicate stooges. One aspect to keep in mind that we are using XPath, particularly inside of our @test in <assert> and <report> elements. This also comes with the same XPath functions that we learned the past 2 weeks. So, useful methods like count() and distinct-value() are still available to us to use. So, as a possible solution to the problem of duplicate stooges, we might count the number of them, and then count the number of stooges with unique names, comparing the two values.

EsRessel commented 4 years ago

Thanks for the tip! I hadn't thought about using functions but will definitely implement them in the future.

One thing that I had a bit of trouble with on the first Schematron exercise was validating that the number of votes for each stooge was between 0 and 100. I tried to use a boolean operator to check for both conditions in one line of code but received an error. I ended up having to split it into two lines. I am wondering why these operators weren't working inside @test when they are legal in XPath? Also, my schema allowed for more than 100% of the vote to be allocated (for example if all stooge elements contained "50"). Any ideas on how to check that the total for the three elements doesn't exceed 100?

djbpitt commented 4 years ago

@EsRessel Boolean operators do work in Schematron, as do functions (thanks, @dap167) and other XPath features. What exactly happened when you tried to use a compound test?

To verify that the percentages total 100, you can add them (XPath sum() function) and compare the total to 100. Where should you hang this test, that is, what should be the value of the @context attribute?

EsRessel commented 4 years ago

@djbpitt I initially tried <sch:assert test=". &gt; 0 and &lt; 100">Votes must be greater than 0 and less than 100.</sch:assert>. I received an error that said "unexpected token "<" at start of expression." However, after looking it over now with fresh eyes, I realize that I originally left out the dot to indicate the node of the XPath expression before the &lt;.

When finding the average, I think that the value of the @context attribute should be /results as the entire node must be checked for the sum rather than the individual <stooge> elements.

djbpitt commented 4 years ago

@EsRessel Yep. The error message told you where to look; it wasn’t expecting the less-than operator because it needed the dot first.

With respect to the value of @context, don’t forget that that value is an XPath pattern, not a full XPath expression. Leading with slash means “fire on a <results> element only if it’s a child of the document node” (that is, only if it’s the root element, since the document node only has one element child, the root). That will work because the only <results> element is the root element, but it’s unnecessarily verbose, and therefore not idiomatic. You can (= should) tell your test to fire on on a <results> element, but you don’t have to have to (= shouldn’t) specify that the <results> element in question must be the root. You’re allowed to take advantage of knowing the structure of your document.