Check for duplicated data with multiple attribute in sibling elements - Schematron

473 views Asked by At

As described in the title, I want to find a way to check duplicated attribute data in XML sibling elements.

I already know the similar question [here] Check for duplicated attribute data in sibling elements - Schematron ,and i've tried through it, not worked for me.

My situation is to check with multiple attributes.

<root>
  <test ZDX="a" XH="1" ps="sdf"/>
  <test ZDX="a" XH="2" ps="dfg"/>
  <test ZDX="a" XH="3" ps="hfgh"/>
  <test ZDX="a" XH="2" ps="ertewr"/><!--same with the 2nd line-->
</root>

I need the <test> element to be unique with ZDX and XH attribute. all the sibling element of test should satisfy that both ZDX and XH attribute can't be equal to another test at the same time, or then the SchemaTron validate error is fired.

i have tried this way,

<rule context="/root/test">
  <assert test="count(self::test) = count(self::test[not(@ZDX=preceding-sibling::test/@ZDX and @XH=preceding-sibling::test/@XH)])">
  test is not unique
  </assert>
</rule>

it works fine with the situation above ,but not work for situation below

<root>
  <test ZDX="a" XH="1" ps="sdf"/>
  <test ZDX="a" XH="2" ps="dfg"/>
  <test ZDX="a" XH="3" ps="hfgh"/>
  <test ZDX="a" XH="4" ps="ertewr"/>
  <test ZDX="b" XH="5" ps="ndmfj"/>
  <test ZDX="b" XH="6" ps="yuoi"/>
  <test ZDX="b" XH="4" ps="qwrew"/><!--conflict with the 4th line-->
</root>

in the last test element, the XH="4" will fire the validation, if i change the last line <test ZDX="b" XH="4" ps="qwrew"/>to <test ZDX="b" XH="7" ps="qwrew"/>,it turns to be unique,and won't fire the validation.

so,how can i check with both ZDX and XH in one Schematron Test phrase?

1

There are 1 answers

0
Stefan Jung On

This should work

<sch:pattern id="duplicate-attribute" abstract="true">
    <sch:rule context="$element">
        <sch:report test="@$attribute = following-sibling::$element/@$attribute 
            or @$attribute = preceding-sibling::$element/@$attribute">
            Duplicate '$attribute' attribute value found
        </sch:report>
    </sch:rule>
</sch:pattern>

<sch:pattern is-a="duplicate-attribute">
    <sch:param name="element" value="test"/>
    <sch:param name="attribute" value="XH"/>
</sch:pattern>

<sch:pattern is-a="duplicate-attribute">
    <sch:param name="element" value="test"/>
    <sch:param name="attribute" value="ZDX"/>
</sch:pattern>