Reputation: 31948
I try to validate this (XSD : http://www.imsglobal.org/xsd/imsrdceo_rootv1p0.xsd) :
<?xml version="1.0" encoding="utf-8"?>
<rdceo xmlns="http://www.imsglobal.org/xsd/imsrdceo_rootv1p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsrdceo_rootv1p0 http://www.imsglobal.org/xsd/imsrdceo_rootv1p0.xsd http://www.w3.org/XML/1998/namespace http://www.w3.org/2001/xml.xsd">
<identifier>5040d336776eb</identifier>
<title>
<langstring xml:lang="en">titre</langstring>
</title>
</rdceo>
But it says (on various sites and with my PHP code):
The attribute 'xml:lang' is not allowed
Here is my PHP code.
<?php
class RDCEOObjectiveBuilder {
public $id,
$title,
$description;
public function build() {
$dom = new DOMDocument('1.0', 'utf-8');
$root = $dom->createElementNS(
'http://www.imsglobal.org/xsd/imsrdceo_rootv1p0',
'rdceo'
);
$root->setAttributeNS(
'http://www.w3.org/2000/xmlns/' ,
'xmlns:xsi',
'http://www.w3.org/2001/XMLSchema-instance'
);
$root->setAttributeNS(
'http://www.w3.org/2001/XMLSchema-instance',
'xsi:schemaLocation',
'http://www.imsglobal.org/xsd/imsrdceo_rootv1p0 http://www.imsglobal.org/xsd/imsrdceo_rootv1p0.xsd http://www.w3.org/XML/1998/namespace http://www.w3.org/2001/xml.xsd'
);
$id = $dom->createElementNS('http://www.imsglobal.org/xsd/imsrdceo_rootv1p0', 'identifier', $this->id);
$title = $dom->createElementNS('http://www.imsglobal.org/xsd/imsrdceo_rootv1p0', 'title');
$title_lang = $dom->createElementNS('http://www.imsglobal.org/xsd/imsrdceo_rootv1p0', 'langstring', $this->title);
$title_lang->appendChild(new DOMAttr('xml:lang', 'en'));
$title->appendChild($title_lang);
$root->appendChild($id);
$root->appendChild($title);
$dom->appendChild($root);
$dom->schemaValidate('imsrdceo_rootv1p0.xsd');
$dom->formatOutput = true;
return $dom->saveXML();
}
}
$test = new RDCEOObjectiveBuilder();
$test->id = uniqid();
$test->title = 'titre';
echo $test->build();
?>
I don't understand why xml:lang
is not allowed... In every examples on http://www.imsglobal.org/competencies/ (the ones who created the xsd), they uses xml:lang
Example : http://www.imsglobal.org/competencies/Examples/MadeUp_Examplev1.xml
Can you tell me why ? Thanks a lot !
Upvotes: 3
Views: 1331
Reputation: 21638
The key thing here is the use of the xs:anyAttribute on the langstring element, it's processing clause which is strict, and how xml:lang
is supposed to work.
strict means the XML processor must obtain the schema for the required namespaces and validate any attribute from those namespaces.
The thing, any decent XML Schema processor is supposed to have built in support for what I call fundamental schemas; xml.xsd, which describes xml:lang, is just one of them.
In my case, using QTAssistant, your XML validates just fine.
I can tell you that it would've helped other processors if they (the schema authors) would've included an xsd:import to the http://www.w3.org/XML/1998/namespace, even without a schema location, and maybe even explicitly ref the xml:land attribute for content which is subject to i18n.
But they didn't... What you can do now is to use another XSD you write that imports both yours and the xml.xsd and you should be fine. As a not of caution, don't import on the http://www.w3.org/2001/03/xml.xsd schema location, since that link is throttled and you'll get timeouts. Have a local copy and then to that. Something like this:
<?xml version="1.0" encoding="utf-8" ?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns="http://tempuri.org/XMLSchema.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import schemaLocation="..." namespace="http://www.imsglobal.org/xsd/imsrdceo_rootv1p0"/>
<xsd:import schemaLocation="..." namespace="http://www.w3.org/XML/1998/namespace"/>
</xsd:schema>
Upvotes: 1
Reputation: 163262
The element langstring
is defined like this:
<xs:anyAttribute namespace="##other" processContents="strict"/>
which means that it allows attributes from another namespace if and only if there is an attribute declaration for that attribute in your schema. Since they don't import the schema for the XML namespace, there's no declaration for xml:lang in the schema unless you take action to include it. I'm not familiar with the PHP interfaces you are using so I can't tell you the best way to achieve that, but one way would be to define a schema document D that imports both the imsglobal schema and the schema for the XML namespace, and use D as the schema against which you validate the instance.
Another way is the way the cited examples do it: they reference the XML namespace from the xsi:schemaLocation attribute in the instance document.
Upvotes: 3