How to create an XBL control that saves data in two elements? - xsd

I'm trying to tell Orbeon to group 2 fields together in order to capture 2 values as in:
Pounds & Ounces.
<xs:complexType name="rpm-weight">
<xs:sequence>
<xs:element name="weight-lbs" type="rpm-weight-lbs" minOccurs="1" maxOccurs="1"/>
<xs:element name="weight-oz" type="rpm-weight-oz" minOccurs="1" maxOccurs="1">
</xs:sequence>
</xs:complexType>
How can I tell Orbeon that when selecting rpm-weight, it will generate 2 text boxes?

Creating an XBL component is the way to go, which might be tricky if this is the first time you're doing this. A few pointers:
So you can use it in Form Builder, your component needs to bind to one element (with ref). The name of the element will be the name given by form authors to the control in Form Builder (assuming they're not using a custom instance).
Form Builder will create one element in the instance for the control. Since your control needs to have sub-elements, you need to tell Form Builder about those. You can do that using the fb:metadata/fb:template/fb:instance. See for instance how this is done in autocomplete.xbl. E.g. that part of the metadata will look as follows.
Example Form Builder metadata for the XBL:
<fb:metadata xmlns:fb="http://orbeon.org/oxf/xml/form-builder">
...
<fb:templates>
<fb:instance>
<weight-lbs/>
<weight-oz/>
</fb:instance>
<fb:view>
...
</fb:view>
</fb:templates>
</fb:metadata>

Related

Is possible to set a default value as an attribute in an element with other facets defined (XSD)?

Suppose I have:
<xs:element name="fieldName" type="xs:string" minOccurs="1" maxOccurs="1">
<xs:annotation>
<xs:appinfo>
<osd:otherFacets>
<osd:tableRef>
<tablePath>/root/TargetTable</tablePath>
<filter>
<predicate>./targetTableField = "status"</predicate>
</filter>
</osd:tableRef>
</osd:otherFacets>
</xs:appinfo>
</xs:annotation>
</xs:element>
The possible values for fieldName are filtered by status. However, in this case, it is necessary to set a default value as being the PK of the target table which has a field with "status".
Is that possible
The possible values for fieldName are filtered by status. However, in this case, it is necessary to set a default value as being the PK of the target table which has a field with "status".
The targetTable and status are both defined in an <appinfo> annotation. Anything within an <annotation> tag is (by definition) targeted at the human reader or the processing application. It is completely ignored by the XML processor.
Presumably the <appinfo> annotation was generated by some application code. Can you add some code into that application to also generate the required default values? If not, you cannot use XML schema validation to supply the default values and you will need to do that in your processing application.

XML Schema within a schema

The question in short - "can I define a schema within a schema which can be validated as a whole?
Explanation:
Is it possible to define a schema for the following XML. I need to define a schema for "customer". The "customertype" child element itself is a schema. Within the customertype I should have an element called "Source" which is mandatory.
<customer>
<customername>acustomer</customername>
<customertype>
<xs:schema>
<xs:element name="profession">
<xs:complexType>
<xs:sequence>
<xs:element name="Source" type="xs:int" />
<xs:element name="ProfessionName" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
</customertype>
</customer>
Is it possible to Define the schema for this xml so that all the requirements are met?
As Mimo has pointed out, there's no problem defining customertype (or another other element) as containing elements in the XSD namespace, which is what you appear to be asking about.
But if your goal is to be able to validate customer elements (or profession elements, which is what the schema in your example declares), it's hard to imagine a validation architecture in which that's the best way (or even a workable way) to go about it. One reason is that validating a document instance against schema information provided by the instance being validated doesn't produce the same confidence in the data's cleanliness as validating it against a known schema. (Put yourself in the shoes of an adversary seeking to subvert your validation and persuade your system to accept bogus data as valid. If the adversary gets to specify what counts as a valid document instance, how useful is it to know that the document is valid?)
What is it that prevents you from writing a schema and using it in the usual way?
[Addition, 15 October 2012, after OP's comment]
If I've understood your comment of earlier today correctly, your requirement is to allow people other than you to specify the type of the customer element however they like, subject to the proviso that that type must contain a child element named Source, whose type will be xsd:int. You don't specify whether you need access to the type definition they are using or not, so I'll try to consider both the case where you do need it and the case where you don't need it.
Three ways to make this situation work are described below. They have in common that there is
a 'main' schema document that defines a basic version of the schema, and
one or more 'auxiliary' schema documents for use in different situations.
In general, you may find it helpful to find a good textbook on XSD and review what it says about creating a schema from declarations in several schema documents.
(1) One approach uses xsi:type. You define a main schema document in which the customer element has a named type; I'll assume the type is named Customer. The Customer type accepts any element whose first child element is named Source. For example:
<xs:element name="customer" type="Customer"/>
<xs:complexType name="Customer">
<xs:sequence>
<xs:element name="Source" type="xs:int"/>
<xs:any minOccurs="0"
maxOccurs="unbounded"
processContents="lax"/>
</xs:sequence>
<xs:anyAttribute processContents="lax"/>
</xs:complexType>
Those who want a more specific type for the customer element (I'll call them the 'users') provide auxiliary schema documents for your target namespace in which they declare other complex types which restrict Customer. For example, they might want the customer element to contain elements called name, address, and phone number:
<xs:complexType name="Customer-for-us">
<xs:complexContent>
<xs:restriction base="Customer">
<xs:sequence>
<xs:element name="Source" type="xs:int"/>
<xs:element ref="name"/>
<xs:element ref="address"/>
<xs:element ref="phone"/>
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
This is a legal restriction of the Customer type, so the customer element can use it. A document instance might therefore contain an element like:
<customer xsi:type="Customer-for-us">
<Source>83760273</Source>
<name>Willy Wonka</name>
<address> ... </address>
<phone> ... </phone>
</customer>
The document is validated against the schema constructed from their auxiliary schema document, together with the main schema document, so the definition of type Customer-for-us is enforced in the usual way.
By using wildcards and lax validation, the Customer type ensures that users can do anything they like in their version of the type, as long as the first child is named Source and has type int.
(2) A second approach uses a hole in the main schema document.
You write a main schema document as before, including the declaration of the customer element as having type Customer. But the main schema document does not contain a declaration for that type. Instead, you declare the Customer type in an auxiliary schema document, which is combined with the main one at validation time in the usual way (I'd recommend you have a third schema document which serves as a driver and includes the other two, but there are many ways to make it work).
The users who want a more specific Customer type, meanwhile, write their own declaration for the Customer type, subject to the compatibility constraints about the first child named Source and so on. The users use their own driver file, which embeds the main schema document and their version of the auxiliary schema document with their own declaration of the Customer type.
This way, the xsi:type attribute does not need to be used.
(3) A third approach uses the xs:redefine or (in XSD 1.1) the xs:override facility.
You write the main schema document as described in solution (1). The users use xs:redefine or xs:override to redefine Customer as they wish. This answer is already rather long, so I do not propose to include a tutorial on the use of either redefine or override.
It is possible to create a schema importing and using another schema. This defines your customer element with customertype containing a schema:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://xml.netbeans.org/schema/Notes"
xmlns:tns="http://xml.netbeans.org/schema/Notes"
elementFormDefault="qualified">
<xsd:import namespace="http://www.w3.org/2001/XMLSchema"/>
<xsd:element name="customer">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="customername" type="xsd:string"/>
<xsd:element name="customertype">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="xsd:schema"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
The problem is that you have an additional condition on the customertype schema - so you should in theory get the standard XSD schema and modify it, but there are many different ways to satisfy that condition in a schema definition, so it is very tricky (and maybe impossible) to do this 'modification'
Probably a better approach is restrict the possible schemas used inside customertype (e.g. it must be a single element definition with complex type specified directly etc. etc) and write a sub-set of the XSD schema that describe this restricted schema definition.

Unmarshalling based on Concrete Instance

I am a new comer to JaxB World and I am facing one problem w.r.t. unmarshalling of the stored xml content into java class object. Problem description is as follows. Let me know if this is solvable
I have my xsd file which contains following content(this is just a example)
Student info
<xs:complexType name="specialization" abstract="true">
</xs:complexType>
<xs:complexType name="Engineering">
<xs:complexContent>
<xs:extension base="specialization">
<xs:sequence>
<xs:element name="percentage" type="xs:int" minOccurs="0"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Medical">
<xs:complexContent>
<xs:extension base="specialization">
<xs:sequence>
<xs:element name="grade" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
Now all the corresponding java classes are generated by compiling the xsd. Now lets assume in my application i will set the specialization attribute of Student info by constructing Engineering class instance. So after all the operation when i save
the xml file that get saved will have the entry like below
<Student>
<Name>Name1</Name>
<Specialization>
<percentage>78<percentage>
</Specialization>
</Student>
Now when the above content goes for unmarshalling, unmarshalling fails saying unexpected element . I guess this is b'cos Specialization element is of type specialization it calls unmarshalling on itself rather than derived object which is stored.
I hope my explanation is clear. Is there any way that we can unmarshall based on derived class instanse type. The xsd and bindings.xjb file is completely in my control so i can add or modify any entries/info which conveys to unmarshalling rules to unmarshall on derived class.
Thanks for your Suggestion but the it still not working for me.
Here is what I tried
Option #1 - xsi:type
My xsd looks same as what is explained in the example but still the Xsi:type doesn't come in the resulted xml. Do i need to add any other setting while compiling? Which JaxB version should i use for this?
Option#2 - Substitution Groups
When i added the substitution entry part in my xsd, XSD compilation failed saying duplicate names "Engineering" and "Medical". I guess element name and type Name being same compilation cribs(All engineering, Medical,specialization being same both in type definition and element Name)
I can't modify the generated classes as we are using Model driven Architecture. Only thing that is in hand is xsd. Any modification to the xsd is allowed. Ideally First option should have worked. But can't figure out why it is not working. Let me know if you have some suggestion to narrow down the problem.
There are different ways of representing Java inheritance in XML when using JAXB:
Option #1 - xsi:type
In this representation an attribute is used to indicate the subtype being used to populate this element.
<Student>
<Name>Name1</Name>
<Specialization xsi:type="Engineering">
<percentage>78<percentage>
</Specialization>
</Student>
For a detailed example see:
http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-xsitype.htmlhtml
Option #2 - Substitution Groups
Here an element name is used to indicate the subtype. This corresponds to the schema concept of substitution groups and leverages JAXB's #XmlElementRef annotation:
<Student>
<Name>Name1</Name>
<Engineering>
<percentage>78<percentage>
</Engineering>
</Student>
For a detailed example see:
http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-substitution.html

Can XSD elements have more than one <annotation>?

I have a common data schema in XSD that is used by two different applications, A and B, each uses the data differently. I want to document the different business rules per application. Can I do this?
<xs:complexType name="Account">
<xs:annotation app="A">
<xs:documentation>
The Account entity must be used this way for app A
</xs:documentation>
</xs:annotation>
<xs:annotation app="B">
<xs:documentation>
The Account entity must be used this way for app B
</xs:documentation>
</xs:annotation>
<xs:complexContent>
...
The appinfo element is used within an annotation element, and specifies information to be used by applications:
<xs:annotation>
<xs:appinfo>Any well-formed XML content here</xs:appinfo>
</xs:annotation>
Since any XML content is valid, you can create your own app-specific metadata and put it in the appinfo element.
Apparently not, since the XML Schema specification states that annotations, when they are used, must appear at the beginning of an element's content. However, the annotation element can have as many documentation (or appinfo) elements as you wish. You can distinguish these elements using attributes. You can also have multiple children (of any type) within a documentation element.
So, one way of writing your schema might look like this:
<xs:complexType name="Account">
<xs:annotation >
<xs:documentation app="A">
The Account entity must be used this way for app A
</xs:documentation>
<xs:documentation app="B">
The Account entity must be used this way for app B
</xs:documentation>
</xs:annotation>
<xs:complexContent>
...

XSD: difference between Element and Attribute

I'm new to XSD, and I'm quite confused as to when to use attribute, and when to use element?
Why cant we specify minOccurs and maxOccurs in attribute?
Also, why is it we cannot specify use="required" in element?
An element is an XML element - a opening tag, some content, a closing tag - they are the building blocks of your XML document:
<test>someValue</test>
Here, "test" would be an element.
Attributes is an additional info on a tag - it's an "add-on" or an extra info on an element, but can never exist alone:
<test id="5">somevalue</test>
"id" is an attribute.
You cannot have multiple attributes of the same name on a single tag --> minOccurs/maxOccurs makes no sense. You can define required (or not) for an attribute - anything else doesn't make sense.
The elements are defined by their occurrence inside complex types - e.g. if you have a complex type with a <xs:sequence> inside - you are defining that all elements must be present and must the in this particular order:
<xs:complexType name="SomeType">
<xs:sequence>
<xs:element name="Element1" type="xs:string" />
<xs:element name="Element2" type="xs:string" />
</xs:sequence>
</xs:complexType>
Inside an element of that type, the sub-elements "Element1" and "Element2" are required and must appear in this order - there's no need for "required" or not (like with attributes). Whether or not an element is required is defined by the use of minOccurs and maxOccurs; both are =1 by default, e.g. the element must occur, and can only occur once. By tweaking those settings, you can define an element to be optional (minOccurs=0), or allow it to show up several times (maxOccurs > 1).
I'd strongly recommend you check out the W3Schools Tutorial on XML Schema and learn some more about XML schema.
Marc
Example: XSD Format
<xs:complexType name="contactInformation">
<xs:all>
<xs:element name="firstName" type="xs:string" minOccurs="0"/>
<xs:element name="workCountryId" type="xs:long" minOccurs="0"/>
</xs:all>
<xs:attribute name="id" type="xs:long"/>
</xs:complexType>
XML Format
<contactInformation id=100>
<firstname>VELU</firstname>
<workCountryId>120</workCountryId>
</contactInformation>
attribute is optional by default. To specify that the attribute is required, use the use attribute:
e.g. <xs:attribute name="id" type="xs:long" use="required"/>
More about attributes and elements.
A complexType element is an XML element that contains other elements and/or attributes.
The all element specifies that the child elements can appear in any order and that each child element can occur zero or one time.
maxOccurs Optional. Specifies the maximum number of times the element can occur. The value must be 1.
minOccurs Optional. Specifies the minimum number of times the element can occur. The value can be 0 or 1. Default value is 1
An element is an XML node - and it can contain other nodes, or attributes. It can be a simple type or a complex type. It is an XML entity.
An attribute is a descriptor. It can't contain anything and can only be a simple type.
Have a look at this. Of course, you can just google something like "XML element vs attribute"
<element myAttribute="value">
<subElement />
<subElement anotherAttribute="this is an attribute's value">Element value</subElement>
</element>
You can't have more than one attribute with the same name in XML, therefore you can't use minOccurs and maxOccurs for attributes.
You don't need use="required" for elements because you can have minOccurs="1" instead.
It is your choice when to use attributes and when to use elements. Here are some guidelines: http://www.ibm.com/developerworks/xml/library/x-eleatt.html

Resources