<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:annotation>
        <xs:documentation xml:lang="en">
            Product Feed Schema for inventory import into Campaign Control, version 1.1.
            Copyright 2008 Keybroker AB. All rights reserved.
        </xs:documentation>
    </xs:annotation>
    <!-- Strips leading and trailing whitespace and collapses multiple whitespaces into single spaces -->
    <xs:simpleType name="CollapsedString">
        <xs:restriction base="xs:string">
            <xs:whiteSpace value="collapse"/>
        </xs:restriction>
    </xs:simpleType>
    <!-- Strips leading and trailing whitespace, collapses multiple whitespaces into single spaces, and requires its length to be at least 1 -->
    <xs:simpleType name="NonEmptyCollapsedString">
        <xs:restriction base="xs:string">
            <xs:whiteSpace value="collapse"/>
            <xs:minLength value="1"/>
        </xs:restriction>
    </xs:simpleType>
    <!-- Typically USD, EUR, SEK, NOK, GBP -->
    <xs:simpleType name="CurrencyType">
        <xs:restriction base="xs:string">
            <xs:pattern value="[A-Z]{3}"/>
        </xs:restriction>
    </xs:simpleType>
    <!-- Please note: This type allows for prices "17", "17.0", "17.05", "17.050" but not "17.051" -->
    <xs:simpleType name="PriceType">
        <xs:restriction base="xs:decimal">
            <xs:fractionDigits value="2"/>
            <xs:minInclusive value="0.00"/>
        </xs:restriction>
    </xs:simpleType>
    <!-- According to www.unspsc.org -->
    <xs:simpleType name="UnspscType">
        <xs:restriction base="xs:string">
            <xs:pattern value="([0-9]{2}){4,5}"/>
        </xs:restriction>
    </xs:simpleType>
    <!-- According to GS1 standard -->
    <xs:simpleType name="GS1Type">
        <xs:restriction base="xs:string">
            <xs:pattern value="[0-9]+"/>
        </xs:restriction>
    </xs:simpleType>
    
    <xs:simpleType name="TargetCpaValueType">
        <xs:restriction base="xs:decimal">
            <xs:fractionDigits value="2"/>
            <xs:minInclusive value="0.00"/>
        </xs:restriction>
    </xs:simpleType>
    
    <xs:simpleType name="TargetCpaPercentType">
        <xs:restriction base="xs:decimal">
            <xs:fractionDigits value="2"/>
            <xs:minInclusive value="0.00"/>
            <xs:maxInclusive value="100.00"/>
            <!-- Should we allow more than 100% ?? There are reasonable cases for such values!! -->
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="RadiusUnitType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="km"/>
            <xs:enumeration value="miles"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:complexType name="GeoPointType">
        <xs:sequence>
            <xs:element name="latitude" type="xs:decimal" minOccurs="1" maxOccurs="1"/>
            <xs:element name="longitude" type="xs:decimal" minOccurs="1" maxOccurs="1"/>
            <xs:element name="radius" minOccurs="1" maxOccurs="1">
                <xs:complexType>
                    <xs:simpleContent>
                        <xs:extension base="xs:decimal">
                            <xs:attribute name="unit" type="RadiusUnitType" use="required"/>
                        </xs:extension>
                    </xs:simpleContent>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
        <xs:attribute name="excluded" type="xs:boolean" use="optional" default="false"/>
    </xs:complexType>

    <xs:complexType name="CountryCodeType">
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute name="excluded" type="xs:boolean" use="optional" default="false"/>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>

    <xs:complexType name="ProvinceCodeType">
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute name="excluded" type="xs:boolean" use="optional" default="false"/>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>

    <xs:complexType name="MetroCodeType">
        <xs:simpleContent>
            <xs:extension base="xs:integer">
                <xs:attribute name="excluded" type="xs:boolean" use="optional" default="false"/>                
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>

    <xs:complexType name="CityCodeType">
        <xs:sequence>
            <xs:element name="countryCode" type="xs:string" minOccurs="1" maxOccurs="1"/>
            <xs:element name="provinceCode" type="xs:string" minOccurs="1" maxOccurs="1"/>
            <xs:element name="cityName" type="xs:string" minOccurs="1" maxOccurs="1"/>
        </xs:sequence>
        <xs:attribute name="excluded" type="xs:boolean" use="optional"/>
    </xs:complexType>

    <xs:complexType name="TargetsType">
        <xs:sequence>
            <xs:element name="countryCode" type="CountryCodeType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="metroCode" type="MetroCodeType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="provinceCode" type="ProvinceCodeType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="city" type="CityCodeType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="geoPoint" type="GeoPointType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="KeywordsType">
        <xs:sequence>
            <xs:element name="keyword" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
    
    <xs:complexType name="NegativeKeywordsType">
        <xs:sequence>
            <xs:element name="negativeKeyword" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>

    <!-- Strips leading and trailing whitespace, collapses multiple whitespaces into single spaces,
and start with either "http://" or "https://" -->
    <xs:simpleType name="HttpUrlType">
        <xs:restriction base="xs:string">
            <xs:whiteSpace value="collapse"/>
            <xs:pattern value="(http|https)://.+"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:element name="products">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="product" minOccurs="0" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="active" type="xs:boolean" default="true" minOccurs="0"/>
                            <xs:element name="category" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="subCategory" type="CollapsedString" minOccurs="0"/>
                            <xs:element name="unspscCode" type="UnspscType" minOccurs="0"/>
                            <xs:element name="description" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="manufacturer" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="manufacturerProductNumber" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="gs1Code" type="GS1Type" minOccurs="0"/>
                            <xs:element name="productFamily" type="CollapsedString" minOccurs="0"/>
                            <xs:element name="modelName" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="color" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="artist" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="title" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="isbn10" type="GS1Type" minOccurs="0"/>
                            <xs:element name="asin" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="media" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="departureCountry" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="destinationCountry" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="departureCity" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="destinationCity" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="departureAirport" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="departureAirportCode" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="destinationAirport" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="destinationAirportCode" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="carrier" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="hotelName" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="hotelGrade" type="xs:decimal" minOccurs="0"/>
                            <xs:element name="hotelGradeString" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="departureDate" type="xs:date" minOccurs="0"/>
                            <xs:element name="returnDate" type="xs:date" minOccurs="0"/>
                            <xs:element name="journeyLengthDays" type="xs:byte" minOccurs="0"/>
                            <xs:element name="journeyLengthWeeks" type="xs:byte" minOccurs="0"/>
                            <xs:element name="onPromotion" type="xs:boolean" minOccurs="0"/>
                            <xs:element name="promotionCode" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="promotionName" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="selectMe" type="xs:boolean" minOccurs="0"/>
                            <xs:element name="targets" type="TargetsType" minOccurs="0"/>
                            <xs:element name="priceWithTax" type="PriceType" minOccurs="0"/>
                            <xs:element name="priceWithoutTax" type="PriceType" minOccurs="0"/>
                            <xs:element name="originalPriceWithTax" type="PriceType" minOccurs="0"/>
                            <xs:element name="originalPriceWithoutTax" type="PriceType" minOccurs="0"/>
                            <xs:element name="shippingCostWithTax" type="PriceType" minOccurs="0"/>
                            <xs:element name="shippingCostWithoutTax" type="PriceType" minOccurs="0"/>
                            <xs:choice minOccurs="0">
                                <xs:element name="targetCpaValue" type="TargetCpaValueType" minOccurs="0"/>
                                <xs:element name="targetCpaPercent" type="TargetCpaPercentType" minOccurs="0"/>
                            </xs:choice>
                            <xs:element name="inStock" type="xs:boolean" minOccurs="0"/>
                            <xs:element name="quantityForSale" type="xs:integer" minOccurs="0"/>
                            <xs:element name="availableFromDate" type="xs:date" minOccurs="0"/>
                            <xs:element name="availableToDate" type="xs:date" minOccurs="0"/>
                            <xs:element name="reviewRank" type="xs:byte" minOccurs="0"/>
                            <xs:element name="priceComparisonRank" type="xs:byte" minOccurs="0"/>
                            <xs:element name="productUrl" type="HttpUrlType" minOccurs="0"/>
                            <xs:element name="imageUrl" type="HttpUrlType" minOccurs="0"/>
                            <xs:element name="categoryUrl" type="HttpUrlType" minOccurs="0"/>
                            <xs:element name="subCategoryUrl" type="HttpUrlType" minOccurs="0"/>
                            <xs:element name="customUrl1" type="HttpUrlType" minOccurs="0"/>
                            <xs:element name="customUrl2" type="HttpUrlType" minOccurs="0"/>
                            <xs:element name="customUrl3" type="HttpUrlType" minOccurs="0"/>
                            <xs:element name="keywords" type="KeywordsType" minOccurs="0"/>
                            <xs:element name="negativeKeywords" type="NegativeKeywordsType" minOccurs="0"/>
                            <xs:element name="adCopyText1" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="adCopyText2" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="adCopyText3" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="adCopyText4" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="customText1" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="customText2" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="customText3" type="NonEmptyCollapsedString" minOccurs="0"/>
                            <xs:element name="customNum1" type="xs:decimal" minOccurs="0"/>
                            <xs:element name="customNum2" type="xs:decimal" minOccurs="0"/>
                            <xs:element name="customNum3" type="xs:decimal" minOccurs="0"/>
                            <xs:element name="lastUpdated" type="xs:dateTime" minOccurs="0"/>
                        </xs:sequence>
                        <xs:attribute name="sku" type="xs:string" use="required"/>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
            <xs:attribute name="currency" type="CurrencyType" use="required"/>
            <xs:attribute name="lastUpdated" type="xs:dateTime"/>
        </xs:complexType>
        <!-- Below uniqueness specification forces all sku attributes to be unique -->
        <xs:unique name="unique-sku">
            <xs:selector xpath="product"/>
            <xs:field xpath="@sku"/>
        </xs:unique>
    </xs:element>
</xs:schema>
