An XSD attribute to capture "source data field" - xsd

I have a domain model which is intended to generalise several source systems. As such, in certain cases the decision was made to overload data into new a generic field rather than to create several specific fields.
To account for this, when the source systems data is mapped onto the new domain model, I was hoping to record the source fieldname as an attribute, e.g.:
<Event>
<Description sourceField="subject">...</Description>
<Description sourceField="description">...</Description>
<Description sourceField="issue">...</Description>
<...>
</Event>
What would be the appropriate way to add such an attribute into the XSD? Would I need to specifically attach it to every such overloaded field, or is there a general way to allow an attribute across all elements?
Please don't point out that I should just add the extra fields into the domain model if I need to distinguish between the different data - the decision has been made, I just need to work around it!
Thanks in advance.

Not really.
If all your element declarations extend from a common base type definition, then you can add the attribute to the base.
If all your element declarations include an anyAttribute, you can make a global attribute definition for sourceField. Then the validator would at least allow your attribute but not require it. And if the anyAttribute is strict or lax the validator will make sure the attribute's content is valid.

Related

How can I write an XSD which doesn't care what the root element is called?

My XML files have restrictions on the child elements, but it really doesn't matter what the name of the root element is. How can I incorporate this into my XSD? I've tried using <xs:any> but I get:
"S4s-elt-invalid-content.1: The Content Of 'schema' Is Invalid. Element 'any' Is Invalid, Misplaced, Or Occurs Too Often."
So I tried missing the name off the element tag like this: <xs:element> but then I get:
"S4s-att-must-appear: Attribute 'name' Must Appear In Element 'element'."
Use a named type, and tell your validator to start validation at the root element using that type.
(There is one possible hitch with this: XSD 1.0 suggests that as one possible invocation option, but does not require validators to provide it, so there's no guarantee the validator interface you use will support it. Depends on your validator. Worth trying, at least.)
Another way to put this: you already have what you are asking for, because your XSD schema never cares what the root element of your document instance is called. An XSD schema provides a set of element and type declarations (among other things). A validator can be requested to start the validation at any point in the document, not just the root, and with either an element declaration or a type declaration, or in 'lax wildcard mode' (the most common default). If your validator doesn't offer the invocation options you want, it's a flaw in your choice of validator, not a gap in XSD.
I think I might just make the requirement stricter and insist on using a particular tag as the root element. The fact that the application doesn't care is not really a problem.
It seems (to me) strange that this limitation exists, but I am new to XSDs.

How to import two cc both contain compositeData?

I do not know that the question is right? Please do not take it your mind if it is crazy. Actually I am working on xpages application. There I need to do two things, that I want to add the picklist functionality and binding the dynamic data like field_1,field_2,field_3, ... upto n depands on customer choice.I am using the composite data for both custom controls. I can remove the picklist control's composite data and also I can do it by passing the scope variables. But that takes more time than the composite data.
I did not get any error. But the binded documents is not saving.
Is it possible to import the CCs that are having composite Data?
Code for first CC:-
<xc:viewpicklist datasrc="view1" dialogID="dialog1" dialogWidth="700px" dialogTitle="Pick this field value!!!">
<xc:this.viewColumn>
<xp:value>0</xp:value>
<xp:value>1</xp:value>
<xp:value>2</xp:value>
</xc:this.viewColumn>
</xc:viewpicklist>
Code for Second CC:-
<xc:BOM_Partinfo BOM_Partinfo="#{document1}"
TNUM="field#{index+1}" Desc="Desc#{index+1}" quan="Ea#{index+1}"
exp="exp#{index+1}" cap="cap#{index+1}" total="price#{index+1}"
RD="RD#{index+1}" m="manufact#{index+1}"
m_n="manufactnum#{index+1}">
</xc:BOM_Partinfo>
You can read information that is set in the properties of a custom control if it was static in the calling page:
var x = getComponent("yourcomponentid");
x.getPropertyMap().get("parametername");
but you want to propagate a data source from the outer control to the inner control...
You need to plan carefully. If you hand over the data source, then your custom control is dependent on a fixed set of fields in the data source (that would be a parameter of type com.ibm.xsp.model.DocumentDataSource). This would violate the encapsulation principles. So I would recommend you actually hand over data bindings - the advantage: you are very flexible what to bind to (not only data sources, but also beans and scope variables would work then). The trick is you provide the binding name as you would statically type it in (e.g. "document1.subject" or "requestScope.bla" ). In your control you then do
${"#{compositeData.field1}"}
${"#{compositeData.field2}"}
You need one for each field.
You cannot send a document data source to a custom control using composite data parameters.
You can try and use this script instead
http://openntf.org/XSnippets.nsf/snippet.xsp?id=access-datasources-of-custom-controls
Define data source in XP/CC where you want those CCs. Define parameter "dataSourceName" for both CCs. Inside each of them use EL "requestScope[compositeData.dataSourceName].fieldName" everywhere you want to bind to datasource.

Making subtags dependent on an attribute of a parent in XML Schema

I have created an XML file like the following
<monitor>
<widget name="Widgets/TestWidget1">
<state code="VIC" />
<state code="TAS" />
</widget>
<widget name="Widgets/TestWidget2">
<client code="someclient" />
</widget>
</monitor>
The name attribute of the <widget> tag tells the parser what widget to load (they are asp.net user controls).
I am trying to create a schema file for the above, the problem is that inside the <widget> the supported subtags are dependent on the name attribute. So TestWidget1 supports the <state> tag and TestWidget2 supports the <client tag.
Currently my XML Schema file just displays all possible <widget> subtags regardless of whether they are supported or not.
How can I write an XML schema file that will only allow specific subtags based on the name attribute? If this is not possible, what options do I have?
You have several options. The simplest and most direct is to re-think your problem a bit. If the legal content of element E1 and the legal content of element E2 are different, then the simplest design is to call them different things, because in XSD as in DTDs the legal content of an element depends on the element type name. A devil's advocate would ask you "if you want different kinds of widget to obey different rules, why are you telling the validator that they are the same kind of widget? Tell the validator the truth, by giving them different names. So don't call them and so on, call them and ."
In XSD 1.1 you can also use conditional type assignment or assertions to define constraints on the legal combinations of attributes and children, but not every schema-aware editor is going to have the chops necessary to analyse the conditional type assignment rules and attributes and understand what to prompt you with.

XML Schema: How to validate an attribute with multiple keys concatenated?

Let's say I can get XML like this:
<Property Name="Title"/>
<Property Name="Content"/>
<Property Name="Address"/>
<Source properties="Title,Content,Address"/>
How coud I validate the "properties" attribute of "Source", so that any composition of the above listed "Property" items could be checked? (For example: "Title", "Title,Content", all of these concatenations are correct, while "Title, URL" is not correct.)
You can't do that within XML Schema. You can do it with your own higher level of validation based on XSLT, XQuery or Schematron, for example.
xan is right; validating always means, to match a XML file against a given schema. But there is no schema involved here, your problem is instead, to read a data file, and validate later entries against earlier ones (if the box above is supposed to represent one file) or one data file against another data file (if the gap is supposed to be a file separator). Beyond that, a schema defines the structure of elements and attributes and optionally data types (values only, if there is a strict enumeration of valid values). Also no match here, instead you want to verify data against data. Sorry, the tool of a schema mismatches the problem to solve.

Can you use key/keyref instead of restriction/enumeration in XML schema?

Suppose we have a stylesheet which pulls in metadata using the key() function. In other words we have instance documents like this:
<items>
<item type="some_type"/>
<item type="another_type"/>
</items>
and a table of additional data we would like to associate with items during processing:
<item-meta>
<item type="some_type" meta="foo"/>
<item type="another_type" meta="bar"/>
<item type="yet_another_type" meta="baz"/>
</item-meta>
Finally, suppose we want to do schema validation on the instance document, restricting the type attributes to the set of types which occur in item-meta. So in the schema we want to use key/keyref instead of restriction/enumeration. This is because using restriction/enumeration will require making a separate list of valid type attributes.
However, it doesn't look like key/keyref will actually work. Having tried it (with MSXML 6.0) it appears the selector of a schema key won't accept the document() function in its xpath argument, so we can't examine the item-meta data, whether it appears in an external file or in the schema file itself. It looks like the only place we can look for keys is the instance document.
So if we really don't want to have a separate list of valid types, we have to do a pre-validation transform, pulling in the item-meta stuff, then do the validation, then do our original transform. That seems overcomplicated for what ought to be a relatively straightforward use of XML schema and stylesheets.
Is there a better way?
Selectors in key/keyref allow only a very restricted xpath syntax. Short, but not completely accurate: The selector must point to a subnode of the element declared.
The full definition of the restricted syntax is -> here.
So, no I don't see a better way, sorry.
BTW: The W3C states that this restriction was made to make life easier on implementers of XML Schema processors. Keep in mind that one of the design goals of XML Schema was to make it possible to process a document in streaming mode. That explains really a lot of the sometimes seemingly random restrictions of XML Schema.
Having thought about it a little more, I came up with the idea of having the stylesheet do that part of the validation. The schema would define the item type as a plain string, and the stylesheet would emit a message and stop processing if it couldn't look up the item type in the item-meta table.
This solution fixes the original problem of having to write down the list of valid types more than once, but it introduces the problem that validation logic is now mixed in with the stylesheet logic. I don't have enough experience with XSD+XSLT to tell whether this new problem is less serious than the old one, but it seems to be more elegant than what I wrote earlier about pulling the item-meta table into each instance document in a pre-validation transform.
You wouldn't need to stop the XSLT with some error. Just let it produce something that the schema won't validate and that points to the original problem like
<error txt="Invalid-Item-Type 'invalid_type'"/>
Apart from that please keep in mind that there are no discussion threads here. The posts may go up and down, so it's better to edit your question accordingly.
Remember, the philosophy here is "One question, and the best answer wins".

Resources