Re: substitutionGroup across namespaces

When processing the following file:
<?xml version="1.0"?>
<rule-set name="fibonacci"
          xmlns="http://drools.org/rules"
          xmlns:java="http://drools.org/semantics/java">

  <rule name="Recurse" salience="10">
    <parameter identifier="f">
      <java:class>org.drools.examples.fibonacci.Fibonacci</java:class>
    </parameter>
    <java:condition>f.getValue() == -1</java:condition>
    <java:consequence>
      System.err.println( "recurse for " + f.getSequence() );
      drools.assertObject( new Fibonacci( f.getSequence() - 1 ) );
    </java:consequence>
  </rule>
</rule-set>

I get the following error:
    [java] Using drl: fibonacci.java.drl
    [java] (null: 10, 83): src-resolve: Cannot resolve the name 
'rules:class' to
 a(n) 'element declaration' component.
    [java] (null: 23, 46): s4s-elt-invalid-content.1: The content of 
'#AnonType_
parameterrule' is invalid.  Element 'element' is invalid, misplaced, or 
occurs t
oo often.
    [java] 
(jar:file:/D:/java/workspaces/drools/drools-examples/target/drools-ex
amples-2.0-beta-18.jar!/org/drools/examples/fibonacci/fibonacci.java.drl: 
11, 21
): cvc-complex-type.2.4.a: Invalid content was found starting with 
element 'java
:condition'. One of '{"http://drools.org/rules":parameter, 
"http://drools.org/ru
les":condition}' is expected.

Yes I'm using xerces 2.6.2 and I make it aware of the .xsds with the 
following code:
InputStream java = cl.getResourceAsStream( "META-INF/java.xsd" );
InputStream python = cl.getResourceAsStream( "META-INF/python.xsd" );
InputStream groovy = cl.getResourceAsStream( "META-INF/groovy.xsd" );
InputStream rules = cl.getResourceAsStream( "META-INF/rules.xsd" );

java.util.List schemaList = new java.util.ArrayList( );

if ( java != null ) schemaList.add( java );
if ( python != null ) schemaList.add( python );
if ( groovy != null ) schemaList.add( groovy );
if ( rules != null ) schemaList.add( rules );

parser.setProperty( JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA );
parser.setProperty(SCHEMA_SOURCE,( InputStream[] ) schemaList.toArray( 
new InputStream[0] ) );

For reference these are the exact files I'm using to to the validation:
rulex.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://drools.org/rules"
           elementFormDefault="qualified"
           xmlns:rules="http://drools.org/rules">

  <xs:element name="rule-set">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="rules:rule"/>
      </xs:sequence>
      <xs:attribute name="name" use="required" type="xs:string"/>
      <xs:attribute name="description" type="xs:string"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="rule">
    <xs:complexType>
      <xs:sequence>

        <xs:element name="parameter" maxOccurs="unbounded" >
          <xs:complexType>
              <xs:element ref="rules:class"/>
            <xs:attribute name="identifier" use="required" 
type="xs:string"/>
          </xs:complexType>
        </xs:element>


        <xs:element ref="rules:condition" maxOccurs="unbounded"/>


        <xs:element ref="rules:consequence"/>

      </xs:sequence>
      <xs:attribute name="name" use="required" type="xs:string"/>
      <xs:attribute name="salience" type="xs:integer"/>
      <xs:attribute name="no-loop" type="xs:boolean"/>
      <xs:attribute name="description" type="xs:string"/>
    </xs:complexType>

  </xs:element>

  <xs:element name="class"       type="xs:string" abstract="true"/>
  <xs:element name="condition"   type="xs:string" abstract="true"/>
  <xs:element name="consequence" type="xs:string" abstract="true"/>

</xs:schema>
java.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
 targetNamespace="http://drools.org/semantics/java"
 elementFormDefault="qualified"
 xmlns:java="http://drools.org/semantics/java"
 xmlns:rules="http://drools.org/rules">

 <xs:import namespace="http://drools.org/rules"/>

 <xs:element name="class"       type="xs:string" 
substitutionGroup="rules:class"/>
 <xs:element name="condition"   type="xs:string" 
substitutionGroup="rules:condition"/>
 <xs:element name="consequence" type="xs:string" 
substitutionGroup="rules:consequence"/>

</xs:schema>

Hope thats enough information.

Mark




George Cristian Bina wrote:

>
> Hi Mark,
>
> I tried your files and they work without any problems. I saved the 
> first schema as rules.xsd, the second as java.xsd and added a 
> schemaLocation to the import element, then the following sample:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <rule-set xmlns="http://drools.org/rules" 
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>     xsi:schemaLocation="http://drools.org/semantics/java java.xsd 
> http://drools.org/rules rules.xsd" name="test">
>     <rule name="r1">
>         <parameter identifier="test">
>             <class xmlns="http://drools.org/semantics/java"/>
>         </parameter>
>         <condition xmlns="http://drools.org/semantics/java"/>
>         <consequence xmlns="http://drools.org/semantics/java"/>
>     </rule>
> </rule-set>
>
> is valid according with Xerces 2.6.2 (from your similar post on the 
> xerces-j-dev list I guess you are using Xerces).
>
> Hope that helps,
> George
> ---------------------------------------------------------------------
> George Cristian Bina
> <oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
> http://www.oxygenxml.com
>
>
> Mark Proctor wrote:
>
>> In the http://drools.org project we have a base name space:
>> http://drools.org/rules
>> And three semantic namespaces:
>> http://drools.org/semantic/java
>> http://drools.org/semantic/groovy
>> http://drools.org/semantic/python
>>
>> Each namespace xsd is in its own file.
>>
>> A rule is made up of classes, conditions, consequences and at the 
>> moment in the rule.xsd we use the choice feature to allow a user to 
>> specify which one they want:
>>        <xs:choice>
>>          <xs:element ref="java:consequence"/>
>>          <xs:element ref="groovy:consequence"/>
>>          <xs:element ref="python:consequence"/>
>>        </xs:choice>
>> However this has the side affect of coupling the rule.xsd to the 
>> semantic xsds, and as a user only has the semantic xsds in the 
>> classpath that they wish to use they receive errors about the other 
>> namespaces, plus it makes it difficult for users wishing to add more 
>> semantic implementations as they need to alter rules.xsd.
>>
>> To try and remove this coupling we wanted to use some sort of 
>> abstract class in rules.xsd to specify a type, which the semantics 
>> would then extend. It seems the only way to do this is with 
>> substitutionalGroup, however it refuses to work when the elements are 
>> in different files and namespaces.
>>
>> I have included some sample code, any help would be greatly appreciated.
>>
>> Regards
>>
>> Mark
>>
>> -------------------------------
>> <?xml version="1.0" encoding="UTF-8"?>
>> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
>>           targetNamespace="http://drools.org/rules"
>>           elementFormDefault="qualified"
>>           xmlns:rules="http://drools.org/rules">
>>
>>  <xs:element name="rule-set">
>>    <xs:complexType>
>>      <xs:sequence>
>>        <xs:element minOccurs="0" maxOccurs="unbounded" 
>> ref="rules:rule"/>
>>      </xs:sequence>
>>      <xs:attribute name="name" use="required" type="xs:string"/>
>>      <xs:attribute name="description" type="xs:string"/>
>>    </xs:complexType>
>>  </xs:element>
>>
>>  <xs:element name="rule">
>>    <xs:complexType>
>>      <xs:sequence>
>>
>>        <xs:element name="parameter" maxOccurs="unbounded" >
>>          <xs:complexType>
>>            <xs:sequence>
>>              <xs:element ref="rules:class"/>
>>            </xs:sequence>
>>            <xs:attribute name="identifier" use="required" 
>> type="xs:string"/>
>>          </xs:complexType>
>>        </xs:element>
>>
>>        <xs:element ref="rules:condition" maxOccurs="unbounded" />
>>
>>        <xs:element ref="rules:consequence"/>
>>
>>      </xs:sequence>
>>      <xs:attribute name="name" use="required" type="xs:string"/>
>>      <xs:attribute name="salience" type="xs:integer"/>
>>      <xs:attribute name="no-loop" type="xs:boolean"/>
>>      <xs:attribute name="description" type="xs:string"/>
>>    </xs:complexType>
>>    </xs:element>
>>
>>  <xs:element name="class"       type="xs:string" abstract="true"/>
>>  <xs:element name="condition"   type="xs:string" abstract="true"/>
>>  <xs:element name="consequence" type="xs:string" abstract="true"/>
>>
>> </xs:schema>
>> -------------------------------------------
>> <?xml version="1.0" encoding="UTF-8"?>
>> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
>>  targetNamespace="http://drools.org/semantics/java"
>>  elementFormDefault="qualified"
>>  xmlns:java="http://drools.org/semantics/java"
>>  xmlns:rules="http://drools.org/rules">
>>
>>  <xs:import namespace="http://drools.org/rules"/>
>>
>>  <xs:element name="class"       type="xs:string" 
>> substitutionGroup="rules:class"/>
>>  <xs:element name="condition"   type="xs:string" 
>> substitutionGroup="rules:condition"/>
>>  <xs:element name="consequence" type="xs:string" 
>> substitutionGroup="rules:consequence"/>
>>
>> </xs:schema>
>>
>>
>>
>>
>
>
>

Received on Monday, 25 October 2004 10:18:45 UTC