Using XPath 2.0 Within Schema

This should cover W3C XML Schema, Relax NG and DTD related problems.
Parmy
Posts: 6
Joined: Tue Jul 24, 2007 11:48 pm
Location: UK

Using XPath 2.0 Within Schema

Post by Parmy »

Hi

I hope someone can help.

I am currently running Oxygen 7.2.

I am writing a schema which uses key and keyref.

Most of the XPath I use in the "selector" works fine, however when using slightly more complex XPath I get the following error message: "is not valid with respect to the XPath subset supported by XML schema",

Here is an made up example of the problem I am having:

<farm>
<animal type="dog">
<food>
Dog Food
<food/>
</animal>
<animal type="cat">
<food>
Cat Food
<food/>
</animal>
</farm>

<xs:key name="animal_food">
<xs:selector xpath="farm/animal/food"/>
</xs:key>

The key above causes no problems.

<xs:key name="animal_type">
<xs:selector xpath="farm/animal[@type='dog']"/>
</xs:key>

The "animal_type" key above causes the "not valid with respect to the XPath subset supported by schema", error.

I have searched various forums and not found the solution. The problem can be one of the following:

1 - XSD Schema only supports a subset of XPath 1.0. Where can I find the subset of XPath 1.0 supported?

2 - XSD Schema only supports a subset of XPath 2.0. Where can I find the subset of XPath 2.0 supported?

3 - XSD Schema fully supports all XPath 2.0. I'm therefore guessing I need to either:
a - Change a setting in Oxygen so the correct Schema validator is used. The only thing I could find under "Preferences" in the "XML Parser" section is, "Schematron XPath Version". I have selected 2.0. However this made no difference.
b - I'm using MSXML.NET, should I change the parser I am using?
c - Do I need to upgrade to Oxygen version 8?
d - The schema version I am using is http://www.w3.org/2001/XMLSchema. Should I change this?

I have had conflicting advice regarding this issue. However the majortiy suggest that the limiting subset of XPath issue is not a problem with later versions of schema. However no one is certain what I need to do to resolve the problem described in Oxygen. Any suggestion would be greatly appreciated.

Many Thanks

Parmy
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Post by george »

Hi,

It is a limitation the XML Schema added to make implementation easier. The restricted XPath subset allowed by XML Schema is described here:
http://www.w3.org/TR/xmlschema-1/#c-selector-xpath

You can use embedded Schematron rules in XML Schema for instance to perform checks that XML Schema cannot perform. There are examples on the forum if you search, for instance:
http://www.oxygenxml.com/forum/ftopic18 ... schematron

Best Regards,
George
George Cristian Bina
Parmy
Posts: 6
Joined: Tue Jul 24, 2007 11:48 pm
Location: UK

Can't get Schematron to work

Post by Parmy »

Hi George

Thank you for your quick response. I had a look at the example you sent me a link to and read up on Schematron.

I then attempted to put the example you have posted to work using Oxygen 7.2 and it simply does not work.

I'm hoping I've made a simple mistake, but I've copied the Schema you had and then created the following test file:

<?xml version="1.0" encoding="UTF-8"?>
<test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="testXSD.xsd">
<a></a>
<b>data</b>
</test>

I expected the error:

"a is empty then b should also be empty."

However I receive no error, when I click the validate button, everything validates ok. Can you give me some assistance please?

The second question I have is the use of ID and IDREF cross referencing. I'm quite confused how I can do this using Schematron. Using Key and Keyref was quite straight forward. Generate a key and then keyref checks against that key. Schematron if I understand it correctly, works differently. For instance image I had the following:

<asset type="image" id="001"> ... </asset>
<asset type="video" id="002"> ... </asset>
<display><image ref="001"/></display>

In the example above I have two assets, an image (id = 001) and a video (id = 002). The "display" tag tells my application to display an image. What I want validation to do, is ensure the image ref matches the id of an asset whose type is image.

If it were possible using XPath I was hoping to do something like:

<key name="imagecheck">
<selector ="asset[@type='image']"/>
</key>

<keyref refer="imagecheck">
<xs:selector xpath="display/image"/>
<xs:field xpath="@ref"/>
</keyref>

However the problem is the restricted XPath in Schema, so I can't use <selector ="asset[@type='image']"/>.

However I have no idea how to do a similar thing using Schematron, as context and assert do not seem to generate a key or allow the use of key? I know there is a way to do this, I hope you can provide an example to assist.

Thanks in advance.

Parmy
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Post by george »

Hi,

In the first part, you need to tell oXygen that you want to perform also Schematron validation. You can do that adding a processing instruction like below:

<?oxygen SCHSchema="testXSD.xsd"?>

In the second part, see a working example below:

Code: Select all


<?xml version="1.0" encoding="UTF-8"?>
<?oxygen SCHSchema="test.sch"?>
<test>
<asset type="image" id="001"> ... </asset>
<asset type="video" id="002"> ... </asset>
<display>
<image ref="001"/>
<image ref="002"/>
</display>
</test>
test.sch

Code: Select all


<?xml version="1.0" encoding="UTF-8"?>
<s:schema xmlns:s="http://www.ascc.net/xml/schematron">
<s:pattern
name="IDREF should reference an ID of a certain element type only">
<s:rule context="image[@ref]">
<s:assert test="//asset[@id=current()/@ref]/@type='image'">Image references need to be made only to images.</s:assert>
</s:rule>
</s:pattern>
</s:schema>
You can easily embed the rule in an XSD schema if you need that.

Best Regards,
George
George Cristian Bina
Parmy
Posts: 6
Joined: Tue Jul 24, 2007 11:48 pm
Location: UK

Thank you

Post by Parmy »

Hi George

Thank you very much for your guidance - I've made a lot of progress as a result of your efforts.

It's really appreciated - you da man :-)

Cheers

Parmy
Parmy
Posts: 6
Joined: Tue Jul 24, 2007 11:48 pm
Location: UK

schematron and javax.xml.validation

Post by Parmy »

George

One final question.

The XSD file I have created combines both the schema and schematron lanugage.

Schematron instructions are embedded in the schema inside <xs:appinfo> nodes.

As you pointed out to validate in Oxygen using a schema and schematron combined xsd file I have to insert the <?oxygen SCHSchema="testXSD.xsd"?> line into the xml file.

Is there an equivalent I can do with javax.xml.validation?

I'm not sure how to get javax to validate using a combined schema and schematron xsd file.

My guess is I need to create a seperate schematron file and validate twice using the schema and schematron file.

The following code allows schema validation only, it ignores the schematron validation:

import java.io.*;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.*;
import org.xml.sax.SAXException;
import javax.xml.XMLConstants;

public class xmlValidator {

public static void main(String[] args) throws SAXException, IOException {

// 1. Lookup a factory for the W3C XML Schema language
//SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.);

// 2. Compile the schema.
// Here the schema is loaded from a java.io.File, but you could use
// a java.net.URL or a javax.xml.transform.Source instead.
File schemaLocation = new File("D:\\temp\\test.xsd");
Schema schema = factory.newSchema(schemaLocation);

// 3. Get a validator from the schema.
Validator validator = schema.newValidator();

// 4. Parse the document you want to check.
Source source = new StreamSource("D:\\temp\\test.xml");

// 5. Check the document
try {
validator.validate(source);
System.out.println(" is valid.");
}
catch (SAXException ex) {
System.out.println(" is not valid because ");
System.out.println(ex.getMessage());
}

}

}

Any pointers would be appreciated.

Regards

Parmy
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Post by george »

Hi,

Yes, you need to perform the Schematron validation yourself. First extract the Schematron rules from the XML Schema, run them through the Schematron XSLT implementation (skeleton) and you will get an XSLT that represents the Schematron rules. Then pass your document through that that XSLT and you get the result.

You may also take a look at Jing or oNVDL (http://www.oxygenxml.com/onvdl.html). That provides Schematron 1.5 validation though an API so you can eventually skip all the above steps and do the validation in one step.

Best Regards,
George
George Cristian Bina
Parmy
Posts: 6
Joined: Tue Jul 24, 2007 11:48 pm
Location: UK

oNVDL and Schematron

Post by Parmy »

Hi George

Thanks for your suggestions.

I have been looking at both solutions, however I haven't quite managed to get either to work yet.

Using Jing and oNVDL appears to be the better solution; however the documentation I have found is confusing and I've not managed to find any examples using a combined W3C Schema and Schematron schema document.

Can you provide any pointers how the .nvdl file should be set up to force validation using the combined schema document discussed in this post?

Once again any advice would be really appreciated.

Best Regards

Parmy
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Post by george »

Sorry, Jing/oNVDL do not support Schematron embedded in XML Schema, only plain Schematron schemas.

Best Regards,
George
George Cristian Bina
Parmy
Posts: 6
Joined: Tue Jul 24, 2007 11:48 pm
Location: UK

Schematron embedded in XML Schema Jing/oNVDL Java

Post by Parmy »

Hi George

Thanks for your prompt response.

May I ask how Oxygen is able to validate using Schematron embedded in XML Schema? Is this something I can use in Java and do you have any example code I can use?

Thanks again for your support.

Best Regards

Parmy
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Post by george »

Hi,

Exactly as I explained above, it extracts the rules, then applies skeleton to get a stylesheet from the Schematron schema and applies the stylesheet to the XML document.

Regards,
George
George Cristian Bina
Post Reply