search:search options migration from MarkLogic 7 to version 8 - search

I'm trying to migrate a search app written in XQuery from MarkLogic 7 to version 8 and I've hit this Known Incompatibility issue about the constraint namespace in the options. I've tried to add the default json/basic namespace and then a custom namespace, didn't work. When I run the below code in Query Console webpage looses connection and reloads after a few seconds. I've even recreated an element range index, after I installed ML 8 all my DBs were recognized, I've reindexed the target DB. Don't know what else could be wrong. Any guidance would be highly appreciated, thanks!
xquery version "1.0-ml";
import module namespace search = "http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy";
declare variable $options :=
<search:options xmlns:search="http://marklogic.com/appservices/search">
<search:search-option>unfiltered</search:search-option>
<search:page-length>30</search:page-length>
<search:term apply="term">
<search:empty apply="all-results"/>
<search:term-option>punctuation-insensitive</search:term-option>
<search:term-option>stemmed</search:term-option>
</search:term>
<search:grammar>
<search:quotation>"</search:quotation>
<search:implicit>
<cts:and-query strength="20" xmlns:cts="http://marklogic.com/cts"/>
</search:implicit>
<search:starter strength="30" apply="grouping" delimiter=")">(</search:starter>
<search:starter strength="40" apply="prefix" element="cts:not-query">-</search:starter>
<search:joiner strength="10" apply="infix" element="cts:or-query" tokenize="word">OR</search:joiner>
<search:joiner strength="20" apply="infix" element="cts:and-query" tokenize="word">AND</search:joiner>
<search:joiner strength="30" apply="infix" element="cts:near-query" tokenize="word">NEAR</search:joiner>
<search:joiner strength="30" apply="near2" consume="2" element="cts:near-query">NEAR/</search:joiner>
<search:joiner strength="50" apply="constraint">:</search:joiner>
<search:joiner strength="50" apply="constraint" compare="LT" tokenize="word">LT</search:joiner>
<search:joiner strength="50" apply="constraint" compare="LE" tokenize="word">LE</search:joiner>
<search:joiner strength="50" apply="constraint" compare="GT" tokenize="word">GT</search:joiner>
<search:joiner strength="50" apply="constraint" compare="GE" tokenize="word">GE</search:joiner>
<search:joiner strength="50" apply="constraint" compare="NE" tokenize="word">NE</search:joiner>
</search:grammar>
<search:additional-query>
<cts:not-query xmlns:cts="http://marklogic.com/cts">
<cts:or-query>
<cts:collection-query>
<cts:uri>ontology</cts:uri>
<cts:uri>Gemeentes</cts:uri>
<cts:uri>Wijken</cts:uri>
<cts:uri>Buurten</cts:uri>
<cts:uri>Wijk_Hierarchy</cts:uri>
<cts:uri>Buurt_Hierarchy</cts:uri>
<cts:uri>Kerncijfers_wijken_en_buurten_2014</cts:uri>
</cts:collection-query>
<cts:element-query>
<cts:element xmlns:sem="http://marklogic.com/semantics">sem:triples</cts:element>
<cts:or-query/>
</cts:element-query>
</cts:or-query>
</cts:not-query>
</search:additional-query>
<search:debug>false</search:debug>
<search:extract-metadata>
<search:qname elem-name="Vhe"/>
<search:qname elem-name="OpnameType"/>
<search:qname elem-name="Plaats"/>
<search:qname elem-name="Straat"/>
<search:constraint-value ref="Plaats"/>
<search:constraint-value ref="Straat"/>
<search:constraint-value ref="Keuken_Beoordeling"/>
<search:constraint-value ref="Badkamer_Beoordeling"/>
<search:constraint-value ref="location"/>
</search:extract-metadata>
<search:transform-results apply="snippet"/>
<search:constraint name="location">
<search:geo-elem-pair>
<search:parent name="location"/>
<search:lat name="lat"/>
<search:lon name="lng"/>
<search:geo-option>units=miles</search:geo-option>
<search:geo-option>coordinate-system=wgs84</search:geo-option>
<search:heatmap n="50.0006240" s="52.384274889550028" w="5.1864790" e="6.8864790" latdivs="14" londivs="19"/>
</search:geo-elem-pair>
</search:constraint>
<search:constraint name="Plaats">
<search:range type="xs:string" collation="http://marklogic.com/collation/">
<search:element name="Plaats"/>
</search:range>
</search:constraint>
<search:constraint name="Straat">
<search:range type="xs:string" collation="http://marklogic.com/collation/">
<search:element name="Straat"/>
</search:range>
</search:constraint>
<search:constraint name="Complex">
<search:range type="xs:string" collation="http://marklogic.com/collation/">
<search:element name="Complex"/>
</search:range>
</search:constraint>
<search:constraint name="Keuken_Beoordeling">
<search:range type="xs:string" collation="http://marklogic.com/collation/">
<search:element name="Keuken_Beoordeling"/>
</search:range>
</search:constraint>
<search:constraint name="Badkamer_Beoordeling">
<search:range type="xs:string" collation="http://marklogic.com/collation/">
<search:element name="Badkamer_Beoordeling"/>
</search:range>
</search:constraint>
<search:return-metrics>true</search:return-metrics>
<search:return-qtext>true</search:return-qtext>
<search:return-query>false</search:return-query>
<search:return-results>true</search:return-results>
<search:return-similar>false</search:return-similar>
<search:sort-order direction="descending">
<search:score/>
<search:annotation>Relevancy (Desc)</search:annotation>
</search:sort-order>
</search:options>;
search:search("wieer", $options, xs:unsignedLong(1), 150)

As Joe points out, the server may be crashing and automatically restarting. Check ErrorLog.txt to verify that. Make sure you have the very latest release: right now it's 8.0-1.1.
The test case does not crash on my laptop with 8.0-1.1 and the necessary index settings. However I don't have any matching documents so it doesn't do very much. That may mean that the crash, if that's what's happening, requires some of your content too. You could try an empty database to verify that, then try to establish whether or not the problem is linked to a specific set of documents.
If the problem persists, contact support to report it.

I've recreated the DB from scratch, copied data with the latest mlcp from the ML 7 DB to the newly created ML 8 DB. Recreated the indexes, but the crash was still happening. Then, I filtered out from the search options which section caused the crash. It is this one:
<search:constraint name="location">
<search:geo-elem-pair>
<search:parent name="location"/>
<search:lat name="lat"/>
<search:lon name="lng"/>
<search:geo-option>units=miles</search:geo-option>
<search:geo-option>coordinate-system=wgs84</search:geo-option>
<search:heatmap n="50.0006240" s="52.384274889550028" w="5.1864790" e="6.8864790" latdivs="14" londivs="19"/>
</search:geo-elem-pair>
</search:constraint>
Once I removed this, was not really using it in the search results, there were no more issues.

Related

Search with queries constrained to elements using search:search

What i want to do is similar in the following link but we want it using search:search:
Queries Constrained to Elements
Basically we have 2 xmls like the following:
XML-1
<rootElement>
<id>7635940284725382300</id>
<parentElement>
<childElement1>ce1-A</childElement1>
<childElement2>ce2-1</childElement2>
</parentElement>
<parentElement>
<childElement1>ce1-B</childElement1>
<childElement2>ce2-2</childElement2>
</parentElement>
<parentElement>
<childElement1>ce1-C</childElement1>
<childElement2>ce2-3</childElement2>
</parentElement>
</rootElement>
XML-2
<rootElement>
<id>7635940284725382398</id>
<parentElement>
<childElement1>ce1-A</childElement1>
<childElement2>ce2-2</childElement2>
</parentElement>
<parentElement>
<childElement1>ce1-B</childElement1>
<childElement2>ce2-3</childElement2>
</parentElement>
<parentElement>
<childElement1>ce1-C</childElement1>
<childElement2>ce2-4</childElement2>
</parentElement>
</rootElement>
So now what i want to do is to have a match for childElement1 and childElement2 within the same parentElement.
For example:
If i search with values childElement1 = ce1-B and childElement2 = ce2-3, it should only give me XML-2 and not return XML-1.
We have achieved this using the cts:search query as explained in the link:
cts:search (/,
cts:element-query (
xs:QName ('parentElement'),
cts:and-query ((
cts:element-value-query(xs:QName('childElement1'), 'ce1-B', 'exact'),
cts:element-value-query(xs:QName('childElement2'), 'ce2-3', 'exact')
))
)
)
Question:
We are using search:search with different search:constraints? I have read about using container for this but there are no good examples to show how it can be used.
Here is our sample search:search, so need to tweak this to have the same functionality as that shown by cts:search query shown above:
import module namespace search = "http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy";
search:search("childElement1:ce1-B AND childElement2:ce2-3 sort:childElement2ASC"
, <options xmlns="http://marklogic.com/appservices/search">
<term>
<term-option xmlns="http://marklogic.com/appservices/search">unstemmed</term-option>
<empty apply="all-results" />
<term-option>case-insensitive</term-option>
<term-option>wildcarded</term-option>
</term>
<transform-results apply="transformed-result" ns="http://isearchgui/search" at="/customResultSet.xqy" />
<search:constraint name="childElement1">
<search:range type="xs:string" facet="false" collation="http://marklogic.com/collation/en">
<search:path-index ns="http://my.search.com/something">//childElement1</search:path-index>
</search:range>
</search:constraint>
<search:constraint name="childElement2">
<search:range type="xs:string" facet="false" collation="http://marklogic.com/collation/en">
<search:path-index ns="http://my.search.com/something">//childElement2</search:path-index>
</search:range>
</search:constraint>
<search:operator name="sort">
<search:state name="childElement1ASC">
<search:sort-order direction="ascending" type="xs:string">
<search:path-index ns="http://my.search.com/something">//childElement1</search:path-index>
</search:sort-order>
</search:state>
<search:state name="childElement1DES">
<search:sort-order direction="descending" type="xs:string">
<search:path-index ns="http://my.search.com/something">//childElement1</search:path-index>
</search:sort-order>
</search:state>
<search:state name="childElement2ASC">
<search:sort-order direction="ascending" type="xs:string">
<search:path-index ns="http://my.search.com/something">//childElement2</search:path-index>
</search:sort-order>
</search:state>
<search:state name="childElement2DES">
<search:sort-order direction="descending" type="xs:string">
<search:path-index ns="http://my.search.com/something">//childElement2</search:path-index>
</search:sort-order>
</search:state>
</search:operator>
</options>
, 0
, 15);
Hope this helps to answer.
You are on the right track. Use the container option, which works like any other constraint option, then wrap your nested query in parenthesis.
For example:
search:parse('contain:(test one two)',
<options xmlns="http://marklogic.com/appservices/search">
<constraint name="contain">
<container>
<element ns="" name="parentElement"/>
</container>
</constraint>
</options>)
=>
<cts:element-query xmlns:cts="http://marklogic.com/cts">
<cts:element>parentElement</cts:element>
<cts:and-query>
<cts:word-query>
<cts:text xml:lang="en">test</cts:text>
</cts:word-query>
<cts:word-query>
<cts:text xml:lang="en">one</cts:text>
</cts:word-query>
<cts:word-query>
<cts:text xml:lang="en">two</cts:text>
</cts:word-query>
</cts:and-query>
</cts:element-query>
So in your case you would have the main-search string as :
search:search('contain:(childElement1:ce1-B AND childElement2:ce2-3) sort:childElement2ASC', <options ....)

Generating XSD from RelaxNG while keeping root-element restriction

I want to convert the following schema from RNC/RNG to W3C XSD.
default namespace = ""
namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0"
namespace rng = "http://relaxng.org/ns/structure/1.0"
start = starting_risk
starting_risk =
element risk {
element continents { Continents }?
}
Continents = element continent { Continent }+
Continent =
element country { Country }*,
element sea { Sea }*
Country = xsd:string { minLength = "1" maxLength = "100" }
Sea = xsd:string { minLength = "1" maxLength = "100" }
Using trang, I end up with
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="risk">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" ref="continents"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="continents" type="Continents"/>
<xs:complexType name="Continents">
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="continent"/>
</xs:sequence>
</xs:complexType>
<xs:element name="continent" type="Continent"/>
<xs:complexType name="Continent">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="country"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="sea"/>
</xs:sequence>
</xs:complexType>
<xs:element name="country" type="Country"/>
<xs:element name="sea" type="Sea"/>
<xs:simpleType name="Country">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="100"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Sea">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="100"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
The problem is that the hierarchy is lost. The 'risk' element is the root of the schema and the only valid element at that level. In the RNC, the relationship between 'risk' and 'continent' elements is parent to child. But in the XSD, they are siblings. What am I doing wrong/ have I not understood?
You’re not doing anything wrong. I think unfortunately you just can’t use trang to generate an XSD from your RNC schema that preserves the restriction on what’s allowed as the root element.
You could instead manually create an XSD restricted to having risk be the only global element, with all the rest of the elements each being a local element. But (as far as I know) you can’t generate such an XSD using trang. The reason is that (again, as far as I know at least) trang basically always generates XSDs only with global elements.
You might think you could generate an XSD with local elements if you wrote your RNC like this:
start =
element risk {
element continents {
element continent {
element country { xsd:string { minLength = "1" maxLength = "100" } }*,
element sea { xsd:string { minLength = "1" maxLength = "100" } }*
}+
}?
}
That’s basically structured in the same way you’d want to structure your XSD if you did it manually.
But if you run that through trang to generate an XSD, you’ll find that every single element comes out as a global element in the resulting XSD. That’s just how trang always does it.
So unless there’s some magic way I’m unaware of to force trang to do otherwise, your only alternative if you want to restrict your XSD schema to only having risk allowed as the root element is, create the XSD manually.
I guess that could be seen as a design flaw in trang, but arguably the real problem is that XML Schema by design has nothing similar to RelaxNG’s start to explicitly specify a root element.
If XML Schema did have a similar simple way like RelaxNG’s start to specify what’s allowed as the root element, then trang could just output that in the XSD and you’d have what you want.
But because XSD has nothing like start, your only mechanism for restricting your schema to having only one particular root element is to completely (re)structure your XSD into the “local style”.
However, as mentioned earlier in this answer, you unfortunately can’t generate such a “local style” XSD from RelaxNG sources using trang. You instead must separately create the XSD manually.
It’s imaginable trang ideally could have been designed with some option to allow you to generate “local style” XSDs or maybe with some heuristics to somehow infer when that’s the output style it should use. But the reality is, that’s not the way trang actually works, and it’s not going to change.
So while I’m sure that isn’t the answer you were hoping to get, I hope it helps clarify things.

Sitecore: creating new <site> equal to existing one with different hostname causes "Layout not found" error

I want to be able to reach my Sitecore website from two different Hostnames, and to do so I created a new entry under <sites> in web.config; here are the code snippets (I omitted the non relevant parts):
<site name="Site1" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content" hostName="mysyte.dev" />
<site name="Site2" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content" hostName="mysyte.mydev" />
I have saved the config and republished the whole website just to be sure, but to no avail: if I access the second site, I get the "The layout for the requested document was not found." error, apparently generated from requesting layout {00000000-0000-0000-0000-000000000000}.
IIS is configured properly, with both hostnames mapped to the same port in the relevant website - yet only one of them works.
Am I missing something really obvious here?
EDIT: the full site entries are as follows:
<site name="Site1" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content" hostName="mysyte.dev" startItem="/AppName" loginPage="/login" database="master" domain="extranet" allowDebug="true" cacheHtml="true" htmlCacheSize="10MB" registryCacheSize="0" viewStateCacheSize="0" xslCacheSize="5MB" filteredItemsCacheSize="2MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false"/>
<site name="Site2" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content" hostName="mysyte.mydev" startItem="/AppName" loginPage="/login" database="master" domain="extranet" allowDebug="true" cacheHtml="true" htmlCacheSize="10MB" registryCacheSize="0" viewStateCacheSize="0" xslCacheSize="5MB" filteredItemsCacheSize="2MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false"/>
Yes. StartItem is missing. But for what you want, separate multiple hostnames in the same attribute by using the pipe delimiter, instead of two separate site definitions.
What is most likely happening here is that the SiteResolver pipeline process is not actually hitting the site definition you think it should. That's the first place I would look. Make sure you have a default catch-all site defined (no hostName) and drop a basic rendering there so you can easily identify it. That being said, Mark's answer is the way to go.
Edit: Remember also that order of site definitions matters here.
Try with this:
<site name="Site1" hostName="Site1.dev" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content/Site1" startItem="/home" loginPage="/login" database="master" domain="extranet" allowDebug="true" cacheHtml="true" htmlCacheSize="10MB" registryCacheSize="0" viewStateCacheSize="0" xslCacheSize="5MB" filteredItemsCacheSize="2MB" enableAnalytics="true" enablePreview="false" enableWebEdit="false" enableDebugger="false" disableClientData="false" />
<site name="Site2" hostName="Site2.dev" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content/Site1" startItem="/home" loginPage="/login" database="master" domain="extranet" allowDebug="true" cacheHtml="false" htmlCacheSize="10MB" registryCacheSize="0" viewStateCacheSize="0" xslCacheSize="5MB" filteredItemsCacheSize="2MB" enablePreview="false" enableWebEdit="false" enableDebugger="false" disableClientData="false" />`
Set the targetHostName attribute on the 'site' node and set Rendering.SiteResolving to true.
<site name="Site1" hostName="mysyte.dev" targetHostName="mysyte.dev" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content" startItem="/AppName" loginPage="/login" database="master" domain="extranet" allowDebug="true" cacheHtml="true" htmlCacheSize="10MB" registryCacheSize="0" viewStateCacheSize="0" xslCacheSize="5MB" filteredItemsCacheSize="2MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false"/>
<site name="Site2" hostName="mysyte.mydev" targetHostName="mysyte.mydev" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content" startItem="/AppName" loginPage="/login" database="master" domain="extranet" allowDebug="true" cacheHtml="true" htmlCacheSize="10MB" registryCacheSize="0" viewStateCacheSize="0" xslCacheSize="5MB" filteredItemsCacheSize="2MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false"/>

perl libXML crash when validating against XSD

I'm migrating an app to the latest Debian and I get a strange server error when validating XML against a XSD
use strict;
use feature qw( :5.10.0 );
use XML::LibXML;
my $xsd = q{
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="orderid" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
};
my $soap=q{
<soap:Envelope
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<shiporder
orderid="889923"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="shiporder.xsd">
<orderperson>John Smith</orderperson>
<shipto>
<name>Ola Nordmann</name>
</shipto>
</shiporder>
</soap:Body>
</soap:Envelope>
};
my $xmlparser = XML::LibXML->new();
my $doc = $xmlparser->parse_string($soap);
my $nodelist = $doc->getElementsByTagNameNS('http://schemas.xmlsoap.org/soap/envelope/', 'Body');
say $nodelist->[0]->toString();
XML::LibXML::Schema->new(string => $xsd)->validate($nodelist->[0]);
which causes
* glibc detected perl: free(): invalid pointer: 0x0000000001cca220 **
======= Backtrace: ========= /lib/x86_64-linux-gnu/libc.so.6(+0x76d76)[0x7fa0edd5fd76]
/usr/lib/perl5/auto/XML/LibXML/LibXML.so(PmmREFCNT_dec+0xa3)[0x7fa0ed27c543]
/usr/lib/perl5/auto/XML/LibXML/LibXML.so(XS_XML_LibXML_Node_DESTROY+0xeb)[0x7fa0ed260a4b]
/usr/lib/libperl.so.5.14(Perl_pp_entersub+0x58c)[0x7fa0ee7ce70c]
/usr/lib/libperl.so.5.14(Perl_runops_standard+0x16)[0x7fa0ee7c5ce6]
/usr/lib/libperl.so.5.14(Perl_call_sv+0x45b)[0x7fa0ee7619db]
/usr/lib/libperl.so.5.14(Perl_sv_clear+0x559)[0x7fa0ee7d4bd9]
/usr/lib/libperl.so.5.14(Perl_sv_free2+0x52)[0x7fa0ee7d5292]
/usr/lib/libperl.so.5.14(Perl_leave_scope+0x122f)[0x7fa0ee7fccef]
/usr/lib/libperl.so.5.14(Perl_pp_leave+0xf2)[0x7fa0ee7cb112]
/usr/lib/libperl.so.5.14(Perl_runops_standard+0x16)[0x7fa0ee7c5ce6]
/usr/lib/libperl.so.5.14(perl_run+0x3a5)[0x7fa0ee767815]
perl(main+0x149)[0x400f89]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)[0x7fa0edd07ead]
perl[0x400fc1]
======= Memory map: ======== 00400000-00402000 r-xp 00000000 08:01 137813 /usr/bin/perl
and so on
I think it is failing when trying to free the memory allocated. I've tried cloning the objects but nothing seems to stop it. This is failing on a clean install of wheezy and jessie
as #nwellnhof said in a separate answer, validate expects a document as a parameter, rather than a node
So I created a new document from the node and then it validates
my $xmlparser = XML::LibXML->new();
my $doc = $xmlparser->parse_string($soap);
my ($node) = $doc->findnodes('/soap:Envelope/soap:Body/*');
my $newDoc = XML::LibXML::Document->new("1.0");
$newDoc->setDocumentElement($node->cloneNode(1));
say $newDoc;
XML::LibXML::Schema->new(string => $xsd)->validate($newDoc);
The validate method in XML::LibXML::Schema only works with whole documents. libxml2 also provides xmlSchemaValidateOneElement but there are no bindings for this function in XML::LibXML.
EDIT: This was fixed in XML::LibXML 2.0112. Now you can pass nodes to validate.

xsd sequence of any type of element that is an extension of specific complex type

Basically if this was .NET, it would look like this:
ISomething
{
string A { get; }
int B { get; }
}
var somethings = new List<ISomething>();
something.Add(new SomethingSomething());
something.Add(new AnotherSomething());
something.Add(new AnythingSomething());
Basically I want the sequence of elements to be named anything they want to be, as long as their complex type is an extension of a complex type I define.
So it may look something like:
<somethings>
<something-something a="foo" b="0" />
<another-something a="bar" b="1" />
<example:anything-something a="baz" b="2" />
</somethings>
I'm sure this is possible, the alternative I guess is composition, where I have a standard element that can contain a single child that is at least a 'Something'..
Thanks in advance, xsd isn't my strong point.
Edit, ok the closest thing I've found so far is basically:
<somethings>
<something xsi:type="something-something" a="foo" b="0" />
<something xsi:type="another-something" a="bar" b="1" />
<something xsi:type="example:anything-something" a="baz" b="2" />
</somethings>
I guess this is the only way this is handled? if so this isn't so bad, and vs intellisense seems to understand this well enough.
Thanks.
This is a good question. You could do a sequence of "any", which would allow you have arbitrarily named elements inside - but that won't constrain them in any way. Alternately, the schema below constrains the name and the attributes, but nothing else (as in your second example)
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="somethingsType" >
<xs:complexContent>
<xs:restriction base="xs:anyType">
<xs:attribute name="a" type="xs:string"/>
<xs:attribute name="b" type="xs:string"/>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="somethingsSeq" >
<xs:sequence>
<xs:element name="something" type="somethingsType"/>
</xs:sequence>
</xs:complexType>
<xs:element name="somethings" type="somethingsSeq"/>
</xs:schema>
I can't find a way to constrain the type but not the element name.

Resources