I have read a similar topic on the matter:
getting the minOccurs attribute using XSOM from an element
but the answer seemed a bit suboptimal, especially when there are hundreds of elements in one xsd file. Is it really the only way to do this, or is there a simpler way?
I would like to retrieve it from XSElementDecl if it's at all possible.
You can't. It's not a property of the element declaration, it's a property of the element particle, which is the relationship between an element declaration and the content model in which it is used.
Now, if the element declaration is a local declaration then it's true enough it can only be used in one content model, so the declaration and the particle are one-to-one, and in the SCM defined in XSD 1.1 it seems that if {variety} is local then you can get {parent} to find the containing model group, and then go back over the particles of this model group. But XSOM doesn't seem to reflect the {parent} property, which is not surprising, because it's not there in XSD 1.0, and there doesn't seem to be anything corresponding to the {scope} property either.
So, the API doesn't seem to allow navigation from the Element declaration to the particles that use that declaration. But then, how did you find the Element declaration if it wasn't via the particle?
Related
I need to query the names of "available" sub elements of an element node in DOM.
For example if schema says "There can be age, name, occupation elements under person element." then I wanna function like this,
import org.w3c.dom.Element;
Element person_element;
String[] names_of_available_sub_element =
get_available_sub_element_names(person_element);
which makes
names_of_available_sub_element == {"age", "name", "occupation"}.
How can I implement this function?
This isn't easy, but it can be done if you're prepared to put a lot of work in.
There are a number of approaches to getting information from an XSD schema. You could try and process the XSD source code, but I wouldn't recommend that, because there are so many things you have to take into account (wildcards, substitution groups, types derived by restriction and extension, and so on). A better approach is to use some kind of API that gives you access to the information in digested form. For that, some possible suggestions are:
(a) Xerces gives you a Java API providing programmatic access to the compiled schema.
(b) Saxon gives you two possibilities: (i) the SCM file, which is an XML representation of the compiled schema, and (ii) an XPath API giving programmatic access to the compiled schema using extension functions.
Do remember that knowing you're at a "person" element isn't (in the general case) enough to determine what the permitted children are. That's because there can be global and local elements using the name "person", but with different types. Whether this is a problem in your case depends on what you are trying to achieve, which you haven't really explained in much detail.
I am trying to validate an xml against an xsd in java.
In XSD one of the field(tax_id) is defined as manadatory element.
But in my scenario I pass an xml to another component, that component fills the manadatory
field(tax_id).
Before sending that xml to the next component, I have to validate that xml against the xsd.
As, in that XSD element tax_id is defined as mandatory element, I get exception for not filling mandatory element (tax_id).
I can create a new xsd by making tax_id as optional field, but with this we would be having 2 xsds.
Is there any way to skip/ignore few elements while validating in java?
In general, no. The purpose of the XSD is to specify the rules that the document must meet, in order to be valid. You can't ignore or skip some of those rules. If you could, you'd probably have other problems. For example, if required elements were really optional (or could be) then technically any element that was supposed to contain a bunch of other elements could be empty (and still valid) under that more lax validation.
In your situation, you probably have two options:
Change your workflow - make sure the first component populates the XML with the empty tax_id. Then it will validate.
Introduce a second schema - one earlier in the "pipeline" of processing, that doesn't require tax_id. Then validate against that.
In the xml, which way is better when define data in content or in the attribute ? Thanks
<order id='' orderBy='' orderTime=''>
.....
</order>
or
<order id=''>
.....
<orderBy>.. </orderBy>
<orderTime>...</orderTime>
</order>
Depends what the data will be. If the data are just simple strings then the first one will be fine.
The second one is important to use if you need to in the future wrap in CDATA. So if the data is long or may contain html in the future then I suggest using the second form. If you look at twitter's XML feed, you will notice that they prefer using an element for almost all of their properties. Using elements give you flexibility in the future if you need to add more multiple elements of the same type.
Here is an article you should read that discusses this topic.
My advice is to perhaps keep your id in an attribute but the rest in an element.
In general, I prefer to use elements instead of attributes, as elements can later be expanded upon (the "extensible" part of XML). However, when you have a rather specific data type as with both of your examples here, you're probably best off keeping them as attributes - especially if orderTime is a standard XML dateTime type.
I would like to add one more point, if CDATA is not issue, then I prefer as attribute than Element. Order Id, date, count etc., should be attributes. Order Items should be Elements.
Generally speaking, you use an attribute if:
there is only one item (of that name) within the parent node
Otherwise, you use an element if:
there can be more than one item (of that name) within the node, or
the item is complex, i.e., may contain attibutes or sub-elements itself
I have some persisted XML that was generated by XStream, and looks like:
<CalculationDefinition>
<id>47</id>
<version>3</version>
<name>RHO error (pts)</name>
<expression class="com.us.provider.expression.AbsoluteValue">
....
</expression>
</CalculationDefinition>
I want to persist this content differently now, and want to tell XStream to simply ignore the expression element entirely. There's many links around that talk about how to do this with a MapperWrapper (eg XStream JIRA) but as far I can tell it doesn't work for an element that has a 'class' attribute.
This can be worked around by leaving an 'expression' field in the CalculationDefinition, but I'd rather not have to keep it there now that it's not used in code.
You could filter the incoming XML using XSL and removing the expression nodes, before passing it to XStream.
I am using JAXB to generate XML from Java objects, it's a realtime, quite high message rate application and works fine most of the time. However occassionally and without any obvious clues as to why, I am getting duplicate namespace declarations in the generated XML. eg:
<UpdateRequest xmlns="http://xml.mycomp.com/ns/myservice"
xmlns="http://xml.mycomp.com/ns/myservice">
<field1>value</field1>
...
</UpdateRequest>
Has anyone seen this behaviour before?
Check if the xsd code of this class allow the creation of more than 1 instance of the repeated attribute. if so, you can avoid this repetitions setting the number of instances of the xmlns attribute for each UpdateRequest object.
If the problem is your code (maybe there is being created this attribute twice) and you have limited the number of instances of the attribute (as i said above), the program will show an error at runtime complaining that you are trying to insert an attribute already defined.
A solution might be available at this link.
here's the relevant section quoted verbatim from the above link that may be relevant for you:
Similar explicit inclusion of a schema
type in an instance document's element
occurs if you instantiate a JAXB
element using an object of some
(abstract) XML schema base type so
that the element would have the
element tag of the base type.
Second, avoid xs:anySimpleType since
this will also create multiple
references to the namespaces bound to
xsi and xs, and type attributes
containing the actual type. And you
lose JAXB's advantage of having typed
fields in your Java classes so that
you lose all the checks the Java
compiler might do, and for
unmarshalling you'll have to handle
all the conversions yourself.