I am creating a XSD to represent the following XML structure.
<DETAILS>
<REFERENCE></REFERENCE>
<INFORMATION>
<INFO>
<KEY></KEY>
<VALUE></VALUE>
<KEY></KEY>
<VALUE></VALUE>
<KEY></KEY>
<VALUE></VALUE>
<KEY></KEY>
<VALUE></VALUE>
.....
</INFO>
</INFORMATION>
I intend to use the same XSD to generate JAXB annotated java classes using XJC.
I manage to get the following XSD.
<xs:complexType name="DetailsType">
<xs:annotation>
<xs:appinfo>
<jaxb:class name="Details" />
</xs:appinfo>
</xs:annotation>
<xs:sequence>
<xs:element type="xs:int" name="REFERENCE">
<xs:annotation>
<xs:appinfo>
<jaxb:property name="reference" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element type="InformationType" name="INFORMATION">
<xs:annotation>
<xs:appinfo>
<jaxb:property name="Information" />
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="InformationType">
<xs:annotation>
<xs:appinfo>
<jaxb:class name="Information" />
</xs:appinfo>
</xs:annotation>
<xs:sequence>
<xs:element name="INFO" type="InfoType">
<xs:annotation>
<xs:appinfo>
<jaxb:property name="Info" />
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="InfoType">
<xs:annotation>
<xs:appinfo>
<jaxb:class name="Info" />
</xs:appinfo>
</xs:annotation>
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="KEY" type="xs:string" />
<xs:element name="VALUE" type="xs:string" />
</xs:sequence>
</xs:complexType>
However using this XSD, XJC generates Java classes using JAXBElement, something like,
#XmlElementRefs({
#XmlElementRef(name = "KEY", type = JAXBElement.class),
#XmlElementRef(name = "VALUE", type = JAXBElement.class)
})
protected List<JAXBElement<String>> keysAndValues;
For such a trivial XML of sequence of repeating elements, the overhead of using JAXBElement seems quite annoying.
Am I missing something ?
I am open to a different approach for XSD Or can someone provide a way to tell JAXB to generate more meaningful classes (don't use JAXBElement please) ?
Related
Would some kind soul please advice me or help me out with this flat file? I do not know how to achieve what I want.
As you can see below there are a few fields which can be used as tag identifiers.
We have 'S' for the start tag, 'I' for customer information, 'F' for invoice details, 'N' for the note section and lastly 'E' for the end section. As you can see there are repeating records as well and this mix of nesting and the use of positional records is giving me trouble.
So, every F-section (customer) has its own set of repeating invoice with note.
I did try the tips on this wonderful post but in this issue no nesting exists unfortunately.
The strange thing is that I can manage to get what I want if I do not take into consideration the positional records. If I just take the entire data and put it into one field (i.e. entire F without positioning) I can get the structure right and that includes the repeating. But they are positional, I, F and N and all my struggle always yields in an error either stating that it is looking for a tag identifier letter or that it is looking for a carriage return and end of line. Any help would be greatly appreciated as I have been struggling with this for quite a while now.
Sample file:
S
I02710242Company name 01 Postboks 123 Sum 010223 14 15 50 54 9597598396200468 NO N
F141220178065428 00000102700-13012018000000080654288
NINK !!!!!!!!!!!
F141220178065429 00000197200-13012018000000080654296
NINK !!!!!!!!!!!
I02710242Company name 02 Postboks 234 Seum 010223 14 16 50 54 9597598396200468 NO N
F050120185794526 00003686250+04022018000000057945263
NINK !!!!!!!!!!!
F141220178065428 00000102700-13012018000000080654288
NINK !!!!!!!!!!!
F141220178065429 00000197200-13012018000000080654296
NINK !!!!!!!!!!!
E000000420000005000030679668+
So what I think I would like to achieve (unless any of you have a better setup) is a schema that looks like this:
S
---I
-F
-N
-F
-N
-I
-F
-N
-F
-N
E
I cooked up an example for you, this will validate with your sample message. I made this without the Wizard. Although the Wizard is a great starting point to get to know some things, complex nesting should just be tried out by hand.
A few things to notice:
Your child order is infix for every repeating record.
You don't have a child order for non-repeating ones, instead, these are specified as positional.
The delimiter is a linefeed if it's repeating. This means on every repeating record you have that delimiter specified or you've specified a default one at the <Schema> level.
I think your problem was partially about recognizing the pattern, as you see in my sample, the pattern is different; After the I row, there is a repeating pattern of F and N rows, which i encapsulated in a record named Repeatingchild.
You could still make your pattern work;
Edit my sample below by removing the Repeatingchild record and placing all elements at the Repeating record.
Set Parser Optimization to Complexity at the <Schema> level, if you don't do this, it will have trouble with the I record.
What's still missing is your exact positional mapping for each field, but I've proven the positionality with the Irecord_part1 and Irecord_part2 i placed in. What i would do next is still use the wizard for each row individually to make all the row elements. So split out each row and run the Wizard on each row type.
To make it even more pretty, you could make individual schema's representing the header and the trailer. So i guess the S record would be the header, and the E record would be the trailer.
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="StackOverflow.FlatFileSchema1" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" targetNamespace="StackOverflow.FlatFileSchema1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:annotation>
<xs:appinfo>
<b:schemaInfo standard="Flat File" root_reference="Root" default_pad_char=" " pad_char_type="char" count_positions_by_byte="false" parser_optimization="speed" lookahead_depth="3" suppress_empty_nodes="false" generate_empty_nodes="true" allow_early_termination="true" early_terminate_optional_fields="false" allow_message_breakup_of_infix_root="false" compile_parse_tables="false" />
<schemaEditorExtension:schemaInfo namespaceAlias="b" extensionClass="Microsoft.BizTalk.FlatFileExtension.FlatFileExtension" standardName="Flat File" xmlns:schemaEditorExtension="http://schemas.microsoft.com/BizTalk/2003/SchemaEditorExtensions" />
</xs:appinfo>
</xs:annotation>
<xs:element name="Root">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="delimited" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" sequence_number="1" child_delimiter_type="hex" child_order="infix" child_delimiter="0x0A" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="0" />
</xs:appinfo>
</xs:annotation>
<xs:element minOccurs="1" maxOccurs="1" name="SRecord">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="positional" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" sequence_number="1" tag_name="S" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="0" />
</xs:appinfo>
</xs:annotation>
<xs:element name="Srecord" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="1" pos_length="200" />
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element minOccurs="0" maxOccurs="unbounded" name="Repeating">
<xs:annotation>
<xs:appinfo>
<b:recordInfo sequence_number="2" structure="delimited" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" child_delimiter_type="hex" child_delimiter="0x0A" child_order="infix" repeating_delimiter_type="hex" repeating_delimiter="0x0A" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="0" />
</xs:appinfo>
</xs:annotation>
<xs:element minOccurs="0" maxOccurs="unbounded" name="IRecord">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="positional" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" sequence_number="1" tag_name="I" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="0" />
</xs:appinfo>
</xs:annotation>
<xs:element name="Irecord_part1" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="1" pos_length="133" />
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="Irecord_part2" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo sequence_number="2" justification="left" pos_length="200" />
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element minOccurs="0" maxOccurs="unbounded" name="Repeatingchild">
<xs:annotation>
<xs:appinfo>
<b:recordInfo sequence_number="2" structure="delimited" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" child_delimiter_type="hex" child_delimiter="0x0A" child_order="infix" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="0" />
</xs:appinfo>
</xs:annotation>
<xs:element minOccurs="0" maxOccurs="unbounded" name="FRecord">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="positional" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" sequence_number="1" tag_name="F" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="0" />
</xs:appinfo>
</xs:annotation>
<xs:element name="Frecord" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="1" pos_length="174" />
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element minOccurs="0" maxOccurs="unbounded" name="NRecord">
<xs:annotation>
<xs:appinfo>
<b:recordInfo sequence_number="2" structure="positional" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" tag_name="N" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="0" />
</xs:appinfo>
</xs:annotation>
<xs:element name="Nrecord" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="1" pos_length="229" />
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="ERecord">
<xs:annotation>
<xs:appinfo>
<b:recordInfo structure="positional" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" tag_name="E" sequence_number="3" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:appinfo>
<b:groupInfo sequence_number="0" />
</xs:appinfo>
</xs:annotation>
<xs:element name="Erecord" type="xs:string">
<xs:annotation>
<xs:appinfo>
<b:fieldInfo justification="left" sequence_number="1" pos_length="29" />
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
The trick is, in one step of the Wizard, you select an entire repeating group (I...N) and set that of one Repeating element.
The Wizard will then drill down into the I...N and have you define sub-records, which can also be repeating Groups or Records with Fields.
There's nothing wrong with running the Wizard multiple times to get the structure right. We've all done it...many times.
I have tried to convert XSD to JAXB classes using mave-jaxb2 plugin and jaxb2-basics simplify plugin.
The configuration in pom.xml is available in this post
sample.xsd (complex choice type)
<xs:complexType name="doclist">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="document1" type="type1">
<xs:annotation>
<xs:appinfo>
<simplify:as-reference-property/>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="document2" type="type2">
</xs:element>
</xs:choice>
</xs:sequence>
<xs:attribute name="heading" type="xs:string" />
</xs:complexType>
However the generated JAXB classes have aOrB references.
#XmlElements({
#XmlElement(name = "document1", type = Type1.class),
#XmlElement(name = "document2", type = Type2.class)
})
protected List<Object> document1OrDocument2;
You have an elements property so you have to place your annotation on the xs:choice, not on the xs:element. Please see the documentation.
And you most probably want to use <simplify:as-element-property/>.
I have this XML schema:
<xs:element name="lineinfo">
<xs:complexType>
<xs:all>
<xs:element name="done" type="xs:unsignedInt" />
</xs:all>
<xs:attribute name="id" type="xs:long" />
<xs:anyAttribute processContents="skip" />
</xs:complexType>
</xs:element>
but I want to allow any other extra element in the lineinfo tag:
<lineinfo state="assigned" id="175">
<done>4</done>
<todo>6</todo>
</lineinfo>
I tried to add <xs:any /> inside the <xs:all>, but it doesn't seem to be allowed.
I couldn't find a way to do what I wanted, so I ended up adding all "unwanted" tags in my list, with minOccurs set to 0:
<xs:element name="lineinfo">
<xs:complexType>
<xs:all>
<xs:element name="done" type="xs:unsignedInt" />
<xs:element name="todo" minOccurs="0" />
<xs:element name="error" minOccurs="0" />
</xs:all>
<xs:attribute name="id" type="xs:long" />
<xs:anyAttribute processContents="skip" />
</xs:complexType>
</xs:element>
Parent tag of <xs:any> are only choice, sequence. w3cschools #el_any
To use <xs:any> put <xs:sequence> instead of <xs:all>. w3cschools #any
else you could use xs:anyType
xs:anyType is a type, like xs:integer (though xs:anyType is special
in that it can act as a simple or complex type, and it places
essentially no restrictions on the tree that it validates -- think of
it loosely as the Schema language's analog of java.lang.Object).
A sample use would be:
<xsd:element name="value" type="xs:anyType"/>
Anyway if you want use below an example taken from w3cschools #anyattribute
SCHEMA
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
<xs:anyAttribute/>
</xs:complexType>
</xs:element>
<xs:attribute name="gender">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="male|female"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
XML
<person gender="female">
<firstname>Hege</firstname>
<lastname>Refsnes</lastname>
</person>
Hi again SO community,
got another request regarding how to define an XSD schema correctly.
Given I have an XML file like:
<?xml version="1.0" encoding="UTF-8" ?>
<transformation xmlns="http://www.denktmit.de/pdi/ktr" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
http://www.w3.org/2001/XMLSchema-instance
./test.xsd">
<info>
<name>TrafoName</name>
<description>TrafoDescription</description>
</info>
<changedby>LastUser</changedby>
<step>
<type>FileInput</type>
<description>FileInput Step description</description>
<FileInputParameterOne>FileInputParam</FileInputParameterOne>
<another>1</another>
</step>
<step>
<type>Select</type>
<description>Select Step description</description>
<SelectParameterOne>SelectParameterOne</SelectParameterOne>
<SelectParameterTwo>SelectParameterTwo</SelectParameterTwo>
<another>2</another>
</step>
</transformation>
This resembles the style of the transformation files as produced by http://community.pentaho.com/projects/data-integration/
As you can see, each step contains several sequence nodes on top
<type>Select</type>
<description>Select Step description</description>
and on bottom:
<another>2</another>
In between, arbitrary complex xml subtrees may occur. But what exactely max occur is determined by the value in "type". The use case is to store specific configurations for concrete Java classes, that all implement an interface, defining getters/setter for "type", "description" and "another" and defining addtional object structure themself. It would also be sufficient to neglect the order, as long as all the elements, needed for a specific class are somehow present.
I already read:
How to group types & subtypes in XSD
xsd: How to extend a type with an unordered list of elements
Use <xs:all> in XML schema's complexType?
xsd: How to extend a type with an unordered list of elements
And I tried something like
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.denktmit.de/pdi/ktr" elementFormDefault="qualified"
attributeFormDefault="unqualified" xmlns="http://www.denktmit.de/pdi/ktr">
<xs:element name="transformation">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="step" type="fileInputStep"></xs:element>
<xs:element name="step" type="selectStep"></xs:element>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="stepComplexType" abstract="true"></xs:complexType>
<xs:complexType name="fileInputStep">
<xs:complexContent>
<xs:extension base="stepComplexType">
<xs:sequence>
<xs:element name="type" minOccurs="1"
maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string"></xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="description" type="xs:string"
minOccurs="1" maxOccurs="1"></xs:element>
<xs:element name="FileInputParameterOne" type="xs:string">
</xs:element>
<xs:element name="another" type="xs:int" minOccurs="1"
maxOccurs="1"></xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="selectStep">
<xs:complexContent>
<xs:extension base="stepComplexType">
<xs:sequence>
<xs:element name="type" minOccurs="1"
maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="Select"></xs:pattern>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="description" type="xs:string"
minOccurs="1" maxOccurs="1"></xs:element>
<xs:element minOccurs="1" name="SelectParameterOne"
type="xs:string">
</xs:element>
<xs:element minOccurs="1" name="SelectParameterTwo"
type="xs:string">
</xs:element>
<xs:element name="another" type="xs:int" minOccurs="1"
maxOccurs="1"></xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
But it is not working, telling me:
Multiple annotations found at this line: validation against this
schema, ambiguity would be created for those two particles.
- Start tag of element
- cos-element-consistent: Error for type '#AnonType_transformation'. Multiple elements with name 'step', with different types, appear in
the model group.
Any ideas?
You may use xsd Group. Here's an sample for your reference
XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="transformation">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="step" type="stepType"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="stepComplexType" abstract="true"></xs:complexType>
<xs:group name="selectParamGroup">
<xs:sequence>
<xs:element name="SelectParameterOne" type="xs:string" minOccurs="1" maxOccurs="1">
</xs:element>
<xs:element name="SelectParameterTwo" type="xs:string" minOccurs="1" maxOccurs="1">
</xs:element>
</xs:sequence>
</xs:group>
<xs:group name="paramGroup">
<xs:choice>
<xs:element name="FileInputParameterOne" type="xs:string">
</xs:element>
<xs:group ref="selectParamGroup">
</xs:group>
</xs:choice>
</xs:group>
<xs:complexType name="stepType">
<xs:complexContent>
<xs:extension base="stepComplexType">
<xs:sequence>
<xs:element name="type" minOccurs="1"
maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string"></xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="description" type="xs:string"
minOccurs="1" maxOccurs="1"></xs:element>
<xs:group ref="paramGroup"></xs:group>
<xs:element name="another" type="xs:int" minOccurs="1"
maxOccurs="1"></xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
XML:
<?xml version="1.0" encoding="UTF-8" ?>
<transformation>
<step>
<type>FileInput</type>
<description>FileInput Step description</description>
<FileInputParameterOne>FileInputParam</FileInputParameterOne>
<another>1</another>
</step>
<step>
<type>Select</type>
<description>Select Step description</description>
<SelectParameterOne>SelectParameterOne</SelectParameterOne>
<SelectParameterTwo>SelectParameterTwo</SelectParameterTwo>
<another>2</another>
</step>
</transformation>
Can anyone point me as to why the unique element in my XSD is not forcing unique-ness? This should throw an error because the last ScreenResult element does not contain a unique value for the Type attribute. I should also note that I'm truly after forcing one of each Type within ScreenResults (ScreenResult is required to exist 3 times, there are 3 types of screens and I am requiring unique-ness) so if there is a better way to accomplish that, I'm all for that as well.
Thank you.
Here is my XML snippet:
<ScreenResults>
<ScreenResult Type="Screen Type A">1</ScreenResult>
<ScreenResult Type="Screen Type B">1</ScreenResult>
<ScreenResult Type="Screen Type B">2</ScreenResult>
</ScreenResults>
Here is my XSD snippet (also note that my original XSD snippets span multiple files but I have verified all of my namespaces are correct):
<xs:element name="ScreenResults" type="import:ScreenResults" minOccurs="0" maxOccurs="1">
<xs:unique name="UniqueScreenResults">
<xs:selector xpath="ScreenResult" />
<xs:field xpath="#Type" />
</xs:unique>
</xs:element>
<!--============ ScreenResults =============-->
<xs:complexType name="ScreenResults">
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="ScreenResult" minOccurs="3" maxOccurs="3">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="enum:ScreenResult">
<xs:attribute name="Type" type="enum:ScreenType" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<!--============= ScreenType =============-->
<xs:simpleType name="ScreenType">
<xs:restriction base='xs:token'>
<xs:enumeration value='Screen Type A' >
<xs:annotation>
<xs:documentation>1</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value='Screen Type B' >
<xs:annotation>
<xs:documentation>2</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value='Screen Type C' >
<xs:annotation>
<xs:documentation>3</xs:documentation>
</xs:annotation>
</xs:enumeration>
</xs:restriction>
</xs:simpleType>
<!--============ ScreenResult ============-->
<xs:simpleType name="ScreenResult">
<xs:restriction base='xs:token'>
<xs:enumeration value='1' >
<xs:annotation>
<xs:documentation>Positive</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value='2' >
<xs:annotation>
<xs:documentation>Negative</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value='3' >
<xs:annotation>
<xs:documentation>Not administered</xs:documentation>
</xs:annotation>
</xs:enumeration>
</xs:restriction>
</xs:simpleType>
I'm posting my solution for anyone else who runs into this problem.
Although I had asserted that all of my namespaces were correct, that was, of course the problem. All of the namespaces were correct except on the unique element itself.
I erroneously assumed that the unique element would not need to prefix a namespace as it was within the context. But that is not the case. Since I did declare a default namespace for the file, I still needed the prefix.
So my only change, and the solution, is as follows:
<xs:element name="ScreenResults" type="import:ScreenResults" minOccurs="0" maxOccurs="1">
<xs:unique name="UniqueScreenResults">
<xs:selector xpath="import:ScreenResult" />
<xs:field xpath="#Type" />
</xs:unique>
</xs:element>