Reputation: 45
I am new to XML and XML Schema. I set up an XML file and an XML schema. I am not 100% familiar with namespaces.
I get the following errors in the XML schema:
I get the following errors in the XML file:
I do not know why 'childrenType' is not defined, because it is defined further down in the XSD document. I suspect that this is a namespace issue.
What I am trying to represent with the XSD schema:
XSD File:
<?xml version="1.0" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3schools.com" elementFormDefault="qualified">
<xs:complexType name="NodeOperandType">
<xs:sequence>
<!-- <xs:element name="operand" type="xs:string" /> -->
<xs:element name="test" type="xs:string" />
<xs:element name="children" type="childrenType" minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="NodeStringExpressionType">
<xs:sequence>
<!-- <xs:element name="string_expression" type="xs:string" /> -->
<xs:element name="test" type="xs:string" />
<xs:element name="test_string" type="xs:string" />
<xs:element name="case_sensitive" type="xs:boolean" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="NodeType">
<xs:choice>
<xs:element name="NodeOperand" type="NodeOperandType" minOccurs="1" maxOccurs="1" />
<xs:element name="NodeStringExpression" type="NodeStringExpressionType" minOccurs="1" maxOccurs="unbounded" />
</xs:choice>
</xs:complexType>
<xs:complexType name="childrenType">
<xs:sequence>
<xs:element name="Node" type="NodeType" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="BinaryExpressionTreeBoolean">
<xs:sequence>
<xs:element name="Node" type="NodeType" minOccurs="1"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
XML File:
<?xml version="1.0" ?>
<BinaryExpressionTreeBoolean xmlns="http://www.w3schools.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://www.w3schools.com file:///C:/XML/file_root.xsd">
<Node>
<NodeOperandType>
<test>"or"</test>
<children>
<Node>
<NodeStringExpressionType>
<test>"include"</test>
<test_string>"simple"</test_string>
<case_sensitive>"true"</case_sensitive>
</NodeStringExpressionType>
</Node>
<Node>
<NodeStringExpressionType>
<test>"include"</test>
<test_string>"simple"</test_string>
<case_sensitive>"true"</case_sensitive>
</NodeStringExpressionType>
</Node>
</children>
</NodeOperandType>
</Node>
</BinaryExpressionTreeBoolean>
The final XML file is shown below for future reference for anyone else visiting this question.
<?xml version="1.0" ?>
<BinaryExpressionTreeBoolean xmlns="http://www.w3schools.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com file:///C:/XML/file_root.xsd">
<Node>
<NodeOperand>
<test>"or"</test>
<children>
<Node>
<NodeStringExpression>
<test>"include"</test>
<test_string>"simple"</test_string>
<case_sensitive>true</case_sensitive>
</NodeStringExpression>
</Node>
<Node>
<NodeStringExpression>
<test>"include"</test>
<test_string>"simple"</test_string>
<case_sensitive>true</case_sensitive>
</NodeStringExpression>
</Node>
</children>
</NodeOperand>
</Node>
</BinaryExpressionTreeBoolean>
Upvotes: 0
Views: 3066
Reputation: 29022
Since your edit, your question is answerable. But there remain several problems:
You define the type of the <case_sensitive>
element as xs:boolean
, but your content is wrapped in quotes, i.e., "true"
instead of true
. This is not valid; see this SO answer regarding boolean values in XSD.
You are missing the namespace of all of your user defined types. So add an xmlns
definition with the same value as your target namespace to your xs:schema
element. So add
xmlns:tns="http://www.w3schools.com"
to the xs:schema
element. You need this to put the types into a namespace.
Now add the namespace prefix tns
, to all of your user-defined types to reference them in the namespace, i.e. reference the type childrenType
with tns:childrenType
.
Finally, add a root element for your root type. So add
<xs:element name="BinaryExpressionTreeBoolean" type="tns:BinaryExpressionTreeBooleanType" />
to the XSD file, which requires you to change your xs:complexType
's name from BinaryExpressionTreeBoolean
to BinaryExpressionTreeBooleanType
.
Combining all of these changes, your XSD could look like this:
<?xml version="1.0" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3schools.com" elementFormDefault="qualified" xmlns:tns="http://www.w3schools.com">
<xs:complexType name="NodeOperandType">
<xs:sequence>
<!-- <xs:element name="operand" type="xs:string" /> -->
<xs:element name="test" type="xs:string" />
<xs:element name="children" type="tns:childrenType" minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="NodeStringExpressionType">
<xs:sequence>
<!-- <xs:element name="string_expression" type="xs:string" /> -->
<xs:element name="test" type="xs:string" />
<xs:element name="test_string" type="xs:string" />
<xs:element name="case_sensitive" type="xs:boolean" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="NodeType">
<xs:sequence>
<xs:choice>
<xs:element name="NodeOperandType" type="tns:NodeOperandType" minOccurs="1" maxOccurs="1" />
<xs:element name="NodeStringExpressionType" type="tns:NodeStringExpressionType" minOccurs="1" maxOccurs="unbounded" />
</xs:choice>
</xs:sequence>
</xs:complexType>
<xs:complexType name="childrenType">
<xs:sequence>
<xs:element name="Node" type="tns:NodeType" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="BinaryExpressionTreeBooleanType">
<xs:sequence>
<xs:element name="Node" type="tns:NodeType" minOccurs="1"></xs:element>
</xs:sequence>
</xs:complexType>
<xs:element name="BinaryExpressionTreeBoolean" type="tns:BinaryExpressionTreeBooleanType" />
</xs:schema>
And this XSD-1.0 file can validate your above XML after your change all of your boolean string values from "true"
to true
and from "false"
to false
. If you cannot change this, you have three options:
Apply a pre-processing XSLT file that changes these values to the valid ones. This can, for example, be achieved with the following template:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tns="http://www.w3schools.com" version="1.0">
<xsl:output indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tns:case_sensitive/text()">
<xsl:value-of select="translate(.,'"','')" />
</xsl:template>
</xsl:stylesheet>
Change the type of the element <case_sensitive>
to xs:string
.
Express the type in an xs:pattern
. To do this, add the following type:
<xs:simpleType name="caseType">
<xs:restriction base="xs:string">
<xs:pattern value='true|false|\"true\"|\"false\"|1|0'></xs:pattern>
</xs:restriction>
</xs:simpleType>
and then reference this type in the related element:
<xs:element name="case_sensitive" type="tns:caseType" />
After doing all this, the validation will succeed.
Upvotes: 1