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

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".

Related

Add XML documentation for named elements in ValueTuple

With ValueTuple in C# 7, it is now possible to write methods and properties that return or consume composite objects without explicitly declaring a type. These named tuples can however be potentially confusing when no documentation is provided.
As the primary and probably most convenient way of documenting libraries is by using XML documentation, is there any way using XML documentation to provide a description of the variables in a named tuple?
I know the obvious solution is to declare a type and document it accordingly. However, granted that due to some 'reasons' that cannot be done, is it possible to XML document the data members in a ValueTuple?
NB: A similar question was asked before the advent of the ValueTuple.
C# has no special syntax for documenting named elements of a tuple, you will have to use the normal <returns> and <param> elements and explain in words what each named element contains.
Though there is a proposal for adding this capability to the language.

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 do I know if I need an XDocument or XElement?

I understand that they are very similar and that the XDocument represents a whole document and an XElement represents a fragment of a whole document, but they seem to be very similar when it comes to loading and querying/updating the data. I am going to have templates saved to a disk and when I load them, I want to query over them and insert,update, and delete sections of data be it attributes or elements. Does XDocument or XElement make a difference here? Does it make a difference if I build the template on the dynamically first?
For starters, they behave in a different way when loading a document, which means you'll have to write your queries in a different way when you choose one over the other. Except for that, msdn states that
The XDocument class contains the information necessary for a valid XML document. This includes an XML declaration, processing instructions, and comments.
Note that you only have to create XDocument objects if you require the specific functionality provided by the XDocument class. In many circumstances, you can work directly with XElement. Working directly with XElement is a simpler programming model
So I'd stick to XElement, unless any of above mentioned metadata about xml is needed (which doesnt seem to be the case).

Require that an element has another element as a descendant

Is there a way in an xsd schema to require that an element have another element somewhere as a descendant?
For example, element parent requires a descendant desc. This is valid:
<parent>
<a>
<b>
<desc></desc>
</b>
</a>
</parent>
As is this:
<parent>
<c>
<desc></desc>
</c>
</parent>
but this isn't:
<a>
<parent>
<b/>
</parent>
</a>
The potential child elements for parent are many and complicates, so it would be difficult to enumerate every possible valid configuration.
Something like the key/selector schema elements seems like it would work, where I could provide an xpath expression defining the valid locations for desc element, but all of the examples I've found are aimed at matching up the value of attributes.
No, (almost) all XML Schema validation is shallow, called "local" in the spec. Here's one excerpt that emphasizes type validation as "local" validation.
Element Validated by Type If an
element information item is ·valid·
with respect to a ·type definition· as
per Element Locally Valid (Type)
(§3.3.4), [it is marked as] ·validated·.
The only exception is for the identity constraints like uniqueness and key-references which have a broad scope in an XML document but narrow uses.
I don't know if XSD supports what you are trying to do, but there is a work-around.
You could do complex validations with a two-step process:
First simply use your XSD schema for basic validation
Next use an XSLT which does more complex validations, and outputs the result of that validation
This may not plug in well to whatever framework you are working with, but might work well for (partially) custom code. It also has the advantage (over doing the extra validations in code) that you can publish both documents.
From a quick google search, one effort towards this end is Schematron. It actually foregos XSD entirely, and just uses XSLT. It appears to be a published standard:
http://www.schematron.com/

Difference between FieldLinks and Field in Sharepoint

I'm in the middle of trying to copy a custom content type from one web to another. I've googled around and found some examples that use FieldLinks and Fields. I'm kind of lost as to which one to use, since when I get the FieldLinks from my source web, I get 3 fields; while retrieving from Fields only returned me 2 fields... the custom field is missing. I'm pretty darn sure that I've added the fields at the proper level since I did it via the interface. But when retrieving it using code... the numbers just don't add up.
So besides from that strange problem, I want to know what is the difference between FieldLinks and Fields, and when dealing with them in Content Types (programmatically) which one should I use?
Thanks.
SPFields are fields themselves, while SPFieldLinks are references to the fields. This is a good read that will explain things in detail. In general practice, it is safer to use SPFieldLinks when you are working on the actual content type definition. However, I'll give a quick summary here.
Lists and Webs contain the actual fields with field data. A content type, on the other hand, only holds Field Reference, which simply points at the corresponding field in the list or web. This gets a bit confusing, because content types have both an SPFieldLinkCollection and an SPFieldCollection.
The SPFieldLinkCollection is used in the actual definition of the content type, and is what you would want to use in your situation of copying a content type from one web to another. SPFieldLinks correspond to the actual elements in the XML Schema for a content type.
Comparatively, when you call on a content type's SPFieldCollection and retrieve a Field from it, what is actually happening is that the content type is checking the corresponding field reference, and then looking up in the list/web to get the actual field. Basically, think of the SPFieldCollection in the same way a lookup works: it is worthless without both the lookup value and the lookup source.

Resources