Reputation: 6273
I'm working on a project at work, and we're defining some flexible XSD schemas. The idea is to use XML for passing execution instructions for certain frameworks within our application. The core structures for the various execution tasks we're going to build this on will be in a core schema, and that will be referenced by the implementation schemas.
Within my core schema, I have wrapper types. These types are extended in the implementation schema, which allows the elements in the implementation schema to have elements from the core schema as their children.
The problem is that I need the reverse to be true also. I need elements from the core schema to be able to have elements from the implementation schema as their children as well. Here's an example of the XML with what I'm trying to do:
<http:Execution>
<core:Condition>
<core:If test="ognl:'One-Response'.equals(#value)">
<http:POST url="http://localhost:9000/eip/http-post/second" auth="BasicAuth" />
</core:If>
</core:Condition>
</http:Execution>
In that example, the "core" namespace is my core schema, and the "http" namespace is the implementation schema.
http:Execute extends the "extendedWrapperType", and it can accept the core element core:Condition with no issues. core:Condition accepts the child core:If because that is defined in the core schema. However, core:If cannot accept http:POST as its child element, because in the core schema it's not designed to accept it.
I'm hoping to avoid xs:any, although that would be my fallback if all else fails. I'm hoping there is some way to have an element in the core XSD contain a reference where it can accept any child of a type I specify in the core XSD, and then have elements in the http XSD extend that type.
Upvotes: 1
Views: 81
Reputation: 163342
This sounds like a job for substitution groups. In the core schema, define an abstract element declaration to appear as the content of core:If. In the implementation schema, define your specific element as a member of that substitution group. Note that the abstract element can have a type, and the specific element must be of a compatible type (same type or derived therefrom).
Upvotes: 1
Reputation: 21651
If I'm understanding you right, this can't be done - you'd have to circularly import both schemas into each other, and that won't work.
You certainly could use an xs:any
in the core schema, but that's not really an ideal approach.
You might consider defining some kind of core
action complex type (which could perhaps be further restricted/extended in your implementation schema). So, instead of this:
<http:Execution>
<core:Condition>
<core:If test="ognl:'One-Response'.equals(#value)">
<http:POST url="http://localhost:9000/eip/http-post/second" auth="BasicAuth" />
</core:If>
</core:Condition>
</http:Execution>
You'd have something like
<http:Execution>
<core:Condition>
<core:If test="ognl:'One-Response'.equals(#value)">
<core:Action command="POST">
<core:Parameter name="url" value="http://localhost:9000/eip/http-post/second" />
<core:Parameter name="auth" value="BasicAuth" />
</core:Action>
</core:If>
</core:Condition>
</http:Execution>
You could even consider getting rid of core:If
and just moving the test
attribute to Action
.
Upvotes: 0