0
votes

I'm trying to write a check in Schematron that will ensure no elements contain duplicated attribute data. These elements are at a specific location in the XML document, I have the XPATH that locates them.

For example:

should fail because it has duplicate foo and bar attribute values.

<id foo="test1" bar="abc" />
<id foo="test1" bar="abc" /> 

This should pass as the foo attributes are not the same.

<id foo="test1" bar="abc" /> 
<id foo="test2" bar="abc" /> 

I'm not sure if this is too complicated for Schematron.

Any thoughts?

2

2 Answers

0
votes

I don't know Schematron, but if you're able to use XPath 2.0 (which is possible at least with some implementations), deep-equal($val1, $val2) will come in handy.

not(deep-equal(<id foo="test1" bar="abc" />, <id foo="test1" bar="abc" />)) (: false :)
not(deep-equal(<id foo="test1" bar="abc" />, <id foo="test2" bar="abc" />)) (: true :)

If not, there should be a solution using XSLT 1.0, but you will have to construct the recursive comparisons on your own (and I don't know XSLT well enough to do so).

0
votes

I would do it this way in Schematron (checked with XML ValidatorBuddy):

<iso:pattern id="unique name attributes">
  <iso:rule context="id">
    <iso:assert test="count(id) = count(id[not(@foo=preceding-sibling::person/@foo)])">
     Not all foo attributes of the id elements are unique
    </iso:assert>
 </iso:rule>
</iso:pattern>

You can also add a check for the bar attribute here.