An Analysis of XML as the IPP protocol
Robert Herriot, Sun Microsystems
robert.herriot@eng.sun.com
This document is intended to look at how the IPP protocol could be encoded into XML. It also gives the definition of a DTD for the IPP encoding.
The syntax is defined by showing examples in order to make reading easier. Italicized names refer to syntax defined in a section by its name.
I have read through the XML Data document (http:www.w3.org/TR/1998/NOTE-XML-data-0105). It describes solutions that are very similar to the ones that I proposed in the document submitted in mid January. It proposes representations for Boolean and dateTime, and it also proposes a mechanism for specifying the data type of a value when it differs from that specified by the DTD. This solution is identical to the one I proposed except that it uses the name "dt" where I used "type". I have made changes to my document to reflect the XML Data document. The XML data actually proposes using the name space of dt for the "dt" attribute so they are really "dt:dt". But I will keep it simple in this document and use "dt".
The main body of the document deals with the best representation for each type. The appendices look at 4 different representations including the one in the main document. The appendix is for completeness only.
The XML Data document is going in the right direction and makes XML a more attractive alternative.
Introduction
*Table of Contents
*Summary of Findings
*Entity Body
*Operation
*Request
*Response
*AttributeGroups
*Attributes
*AttributeValue
*Text and TextWithLanguage
*Name and NameWithLanguage
*Charset
*NaturalLanguage
*MimeMediaType
*KeywordType
*UriType
*UriSchemeType
*BooleanType
*IntegerType
*EnumType
*DateTimeType
*Resolution
*RangeOfInteger
*SetOf
*Out of Band Values
*Dictionaries
*DTD for IPP
*DTD for Get-Printer-Attributes request
*DTD for Get-Printer-Attributes response
*DTD for IPP Using Schema from XML Data
*DTD for Get-Printer-Attributes request
*DTD for Get-Printer-Attributes response
*Protocol Examples with XML
*Print-Job Request
*Print-Job Response (successful)
*Print-Job Response (failure)
*Print-URI Request
*Create-Job Request
*Get-Jobs Request
*Get-Jobs Response
*Get-Printer-Attributes Request
*Get-Printer-Attributes Response
*Appendix A: Alternate Representation of Attributes
*Appendix B: Alternate Representation of AttributeValues
*Text and TextWithLanguage
*Name and NameWithLanguage
*Charset
*NaturalLanguage
*MimeMediaType
*KeywordType
*UriType
*UriSchemeType
*BooleanType
*IntegerType
*EnumType
*DateTimeType
*Resolution
*RangeOfInteger
*SetOf
*Out of Band Values
*Dictionaries
*
After doing the exercise of defining the IPP protocol in XML and producing a DTD, I have a better understanding of the pros and cons.
On the pro side,
On the con side,
If we wait 6 to 12 months and influence the development of XML and XSL, then XML is probably an excellent solution. But meanwhile, we need to decide whether it is best to proceed with the IPP binary protocol or an interim XML protocol. In both cases, I expect that we will have to produce a new version 2.0 of the protocol.
The following sections define the encoding using XML.
The entity body for all requests except Print-Job and Send-Document and for all responses is of type text/xml. The entity body for Print-Job requests and Send-Document requests is a multipart/related where the first part is text/xml and the second part is document data.
The remainder of this document defines the text/xml part.
I have concluded that a DTD should not be are part of the protocol. Rather it along with an English description is used to define the parser, which is either handwritten or partially generated by machine from the DTD.
A request is encoded as follows:
<?XML version= "1.0" encoding= "UTF-8">
<request operation= "Print-Job" version= "1.0" xml:lang= "en" request-id= "1">
AttributeGroups
</ request >
where Print-Job represents one particular operation. Each operation would have its own value for the "operation" XML attribute. An alternate solution is to have "Print-Job" be the name of the tag. But the solution with a tag name "request" is more symmetric with the response where there is no need to name each response separately.
In this part of the proposal, several IPP operation attributes are encoded as XML attributes. They could have been encoded as XML elements, as some people prefer, but these particular IPP attributes modify the contained AttributeGroups so XML attributes seemed more appropriate. Furthermore, the XML standard defines the attributes "encoding" and "xml:lang" explicitly. The IPP operation attributes handled here include: the IPP version, the charset, the natural language and the request-id. The request-id could be optional with this syntax. The encoding is also optional because XML assumes UTF-8 if there is no encoding specified and the first two bytes are not 0xFEFF (which means UTF-16) follows. The XML version is also included as part of the XML syntax.
A response if encoded as follows
<?XML version= "1.0" encoding= "UTF-8">
< response status = "200" status-message = "OK" version= "1.0" xml:lang= "en" request-id= "1">
AttributeGroups
</ response >
A response is similar to a request except that the XML attribute "operation" is dropped, and the XML attributes "status" and "status-message" are added.
AttributeGroups are a sequence of AttributeGroup’s. The AttributeGroup for operation attributes is encoded:
<operation>
Attributes
</operation>
The AttributeGroups for job, printer and unsupported are encoded in a similar way. A Print-Job operation would be encoded as follows (where Attributes is still not defined).
<?XML version= "1.0" encoding= "UTF-8">
< request operation= "Print-Job" version= "1.0" xml:lang= "en" request-id= "1">
<operation>
Attributes
</operation>
<job>
Attributes
</job>
</ request >
There are several ways to encode an Attribute. Four ways are examined in "Appendix A: Alternate Representation of Attributes". This section will describe the way that I think holds the most promise and the XML Data document proposes as a representation.
Note: The examples in this section use the following attributes:
Name |
Data Type |
priority |
integer |
sides |
keyword |
sides-default |
keyword |
sides-supported |
setOf keywords |
job-k-octets-supported |
rangeOfInteger |
media-supported |
setOf (keywords or names) |
Attributes are represented by surrounding the attribute value by tags containing the attribute name. Values are represented with either a text string or a mixture of text strings and markup, depending on the data type. The DTD specifies the data type, i.e. interpretation of the text. For attributes with a single value, the syntax is:
<AttributeName > AttributeValue </AttributeName>
E.g.
< priority>50</priority>
< sides> one-sided </sides>
< sides-default> one-sided </ sides-default >
If the data type of an attribute value differs from that defined in the DTD, then its data type is specified by the XML "dt" attribute. The syntax is:
<AttributeName dt = "AttributeType" > AttributeValue </AttributeName>
E.g.
< priority dt = "outOfBandType" >unsupported</priority>
Note: that special markup, such as <unsupported> could be used in place of the explicit typing, but this solution requires that such markup names not clash with the markup used for structured values. The explicit data type seems like a simpler solution.
For attributes containing a set of values, each value is surrounded by the "item" tags, which act like parentheses to separate the values. The syntax is:
<AttributeName >
<item> AttributeValue </item>
...
<item> AttributeValue </item>
</AttributeName>
E.g.
< sides-supported >
<item> one-sided </item>
<item> two-sided-long-edge </item>
</ sides-supported >
If the data type of any item differs from that specified by the DTD, then its data type is specified by the XML "dt" attribute in the "item". The syntax is:
<AttributeName >
<item> AttributeValueWithDTDType </item>
...
<item dt= "AttributeType" > AttributeValueWithNonDTDType </item>
</AttributeName>
E.g.
< media-supported >
<item> letter </ item >
< item > legal </ item >
< item dt = "nameType" > fooPaper </ item >
</ media-supported >
For data types which are unstructured and cannot contains quote characters, there could be a short hand which represents and attribute value with an empty element tag and an extra attribute "value" which contains the value. The examples above would then be:
< priority value = "50"/>
< sides value = "one-sided/ >
< sides-default value = "one-sided" />
< priority dt = "outOfBandType" value = "unsupported" />
< sides-supported >
<item value = "one-sided"/ >
<item value = "two-sided-long-edge" / >
</ sides-supported >
< media-supported >
<item value = "letter" />
< item value = "legal"/>
< item dt = "nameType" > fooPaper" </item>
<!-- nameType could contain quote characters, so it is not put in the "value" attribute -->
</ media-supported >
The sections below give the encoding for each IPP data type using the encoding described above. The syntax is explained with examples instead of a syntactic formalism. Examples with single values and with setOf values are shown for each data type unless there is no IPP attribute with a single value or a setOf value.
The following is the encoding of the attribute "job-state-message" with value "out of paper" and data type "textWithLanguage".
<job-state-message xml:lang= "en">out of paper</ job-state-message>
The "text" data type is encoding as above, but with "xml:lang" attribute omitted.
<job-state-message >out of paper</ job-state-message>
All other attributes of type "text" and "textWithLanguage" are encoded in a similar fashion.
There are no "setOf text" or "setOf textWithLanguage" values.
The value "out-of-paper" is a sample value of type "text". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The encoding is similar to text.
The following is the encoding of the attribute "job-name" with value "Mein Stoff" and type "nameWithLanguage" in each of the 4 cases.
< job-name xml:lang= "de">Mein Stoff</ job-name >
The "name" data type is encoding as above, but with "xml:lang" attribute omitted.
All other attributes of type "name" and "nameWithLanguage" are encoded in a similar fashion.
There are no "setOf text" or "setOf textWithLanguage" values.
The value "Mein Stoff" is a sample value of type "name". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The following is the encoding of the attribute "charset-configured" with value "UTF-8" and type "charset".
< charset-configured >UTF-8</ charset-configured >
All other attributes of type "charset" are encoded in a similar fashion except for the charset operation attribute, which uses the text value with no markup e.g.
<?XML version= "1.0" encoding= "UTF-8">
The following is the encoding of the attribute "charset-supported" with values "UTF-8" and "SJIS" and type "setOf charset".
< charset-configured >
<item> UTF-8</item>
<item> UTF-16</item>
</ charset-configured >
All other attributes of type "setOf charset" are encoded in a similar fashion.
The value "UTF-8" is a sample value of type "charset". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The following is the encoding of the attribute "natural-language-configured" with value "en" and type "naturalLanguage".
< natural-language-configured >en</ natural-language-configured >
All other attributes of type "naturalLanguage" are encoded in a similar fashion
The following is the encoding of the attribute "generated-natural-language-supported" with values "en" and "de" and with type "setOf naturalLanguage".
< generated-natural-language-supported >
<item> en </ item >
< item >de</ item >
</ generated-natural-language-supported >
All other attributes of type "setOf naturalLanguage" are encoded in a similar fashion.
The value "en" is a sample value of type "naturalLanguage". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The following is the encoding of the attribute "document-format" with value "PostScript" and data type "mimeMediaType.
< document-format> PostScript </ document-format>
All other attributes of type "mimeMediaType" are encoded in a similar fashion
The following is the encoding of the attribute "document-format-supported" with values "PostScript" and "PCL" and data type "setOf mimeMediaType".
< document-format-supported >
<item> PostScript </ item >
< item >PCL</ item >
</ document-format-supported >
All other attributes of type "setOf mimeMediaType" are encoded in a similar fashion.
The value "PostScript" is a sample value of type "mimeMediaType". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The following is the encoding of the attribute "media" with value "letter" and data type "keyword".
< media > letter </ media >
All other attributes of type "keyword" are encoded in a similar fashion.
The following is the encoding of the charset attribute "media-supported" with keyword values "letter" and "legal" and a name value "fooPaper". This example illustrates an attributes with two types of values: keywords and names.
< media-supported >
<item> letter </ item >
< item > legal </ item >
< item dt = "nameType" > fooPaper </ item >
</ media-supported >
All other attributes of type "setOf keyword" are encoded in a similar fashion.
The value "letter" is a sample value of type "keyword". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The following is the encoding of the attribute "job-uri" with value "http:/foo/bar" and data type "uri".
< job-uri > http:/foo/bar </ job-uri >
All other attributes of type "uriType" are encoded in a similar fashion
The following is the encoding of the attribute "printer-uri-supported" with values "http:/foo/bar" and "http://foo/foo" and with data type "setOf uri".
< printer-uri-supported >
<item> http:/foo/bar </ item >
< item > http://foo/foo </ item >
</ printer-uri-supported >
All other attributes of type "uri" are encoded in a similar fashion.
The value "http:/foo/bar" is a sample value of type "uri". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The following is the encoding of the attribute "reference-uri-schemes-supported" with values "http" and "ftp" and with data type "setOf uriScheme".
< reference-uri-schemes-supported >
<item> http </ item >
< item > ftp </ item >
</ reference-uri-schemes-supported >
All other attributes of type "uriScheme" are encoded in a similar fashion.
The value "http" is a sample value of type "uriScheme". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The encoding of boolean values could be done in several ways: "true"/"false", "t"/"f", "1"/"0", "yes"/"no" or "y"/"n". This example will use "1"/"0" ("1" is true and "0" is false), as in the XML Data standard.
The following is the encoding of the boolean attribute "color-supported" with value "1".
< color-supported > 1 </ color-supported >
All other attributes of type "boolean" are encoded in a similar fashion
The value "1" is a sample value of type "boolean". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The following is the encoding of the attribute "priority" with value "50" and data type "integer".
< priority > 50 </ priority >
All other attributes of type "integer" are encoded in a similar fashion.
The following is the encoding of the attribute "number-up-supported" with a "set Of" value of data type "integer" or "rangeOfInteger".
< number-up-supported >
<item dt = "rangeOfIntegerType" > <min>1</ min > <max>4</ max ></ item >
< item > 8 </ item >
</ number-up-supported >
Note: an explicit data type could be omitted for the rangeOfInteger because it can be inferred by the presence of the "min" tag. But then tag names would have to chosen uniquely so they would ambiguously specify the type. So the explicit type seems like a better idea.
All other attributes of type "setOf integer" are encoded in a similar fashion.
The value "50" is a sample value of type "integer". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The following is the encoding of the attribute "orientation-requested " with value "2" and with data type "enum".
< orientation-requested > 2 </ orientation-requested >
All other attributes of type "enum" are encoded in a similar fashion.
The following is the encoding of the attribute "finishings" with values "2" and "3" and with data type "setOf enum".
< finishings >
<item> 2 </ item >
< item > 3 </ item >
</ finishings >
All other attributes of type "setOf enum" are encoded in a similar fashion.
The value "2" is a sample value of type "enum". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The encoding of dateTime values could be done in several ways:
Option 1 is probably the best choice and the one used in this example, though there are many variation (the example shows two of them above). Option 2 has too many English words, and option 3 is too verbose.
The following is the encoding of the attribute "printer-current-time" with value "1998-01-31T15:23:45,234-8:00" (from RFC1903 and ISO 8601) and of data type "dateTime".
< printer-current-time > 1998-01-31T15:23:45,234-8:00 </ printer-current-time >
All other attributes of type "dateTime" are encoded in a similar fashion.
The value "1998-01-31T15:23:45,234-8:00" is a sample value of data type "dateTime". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The encoding of resolution values could be done in several ways:
The following is the encoding of the attribute "printer-resolution" with value option 2 above and data type "resolution".
< printer-resolution > <xfeed>300</ xfeed > <feed>600</ feed > <units>in</ units ></ printer-resolution >
All other attributes of type "resolution" are encoded in a similar fashion
The following is the encoding of the attribute "printer-resolution-supported" with values as in option 2 and of data type "setOf resolution".
< printer-resolution-supported >
<item> <xfeed>300</ xfeed > <feed>300</ feed > <units>in</ units ></ item >
<item> <xfeed>300</ xfeed > <feed>600</ feed > <units>in</ units ></ item >
</ printer-resolution-supported >
All other attributes of type "setOf resolution" are encoded in a similar fashion.
The value above is a sample value of type "resolution". The encoding of each element is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The encoding of rangeOfInteger values could be done in several ways:
The following is the encoding of the attribute "job-k-octets-supported " with value of option 2 and of data type "rangeOfInteger".
< job-k-octets-supported > <min>1</ min > <max>10000</ max ></ job-k-octets-supported >
All other attributes of type "rangeOfInteger" are encoded in a similar fashion
The following is the encoding of the attribute "page-ranges" with values "letter" and "legal" and with data type "setOf rangeOfInteger" in each of the 4 cases.
< page-ranges >
<item> <min>1</ min > <max>5</ max ></ item >
</ page-ranges >
All other attributes of type "setOf rangeOfInteger" are encoded in a similar fashion.
The value above is a sample value of type "rangeOfInteger". The encoding of each element is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The SetOf data type has been demonstrated in previous sections for each data type contained in a SetOf.
The encoding of outOfBand values could be done either with
The "outOfBand" data type is best for all of the encodings. The empty element tags could be used for the first "implicit" encoding, but it would be necessary that all tags used in values be unique so that tags from structured values wouldn’t clash with tags for outOfBand values. I prefer to use the special data type because it is consistent with the use of special data types.
The following is the encoding of the attribute "printer-resolution" with value option 2 above and with a data type of "outOfBand".
< printer-resolution dt = "outOfBandType" > unknown </ printer-resolution >
The following is the encoding of the attribute "finishings" with values "2" and "novalue" in each of the 4 cases. This example is probably artificial because, a printer would probably not return a setOf with a mix of outOfBand values and normal values.
< finishings >
<item> 2 </ item >
item dt = "outOfBandType" > no-value </ item >
</ finishings >
The following is the encoding of a future dictionary attribute "foo" with a value of data type "dictionary".
< foo >
<bar> 1 </ bar >
<zap> stuff </ zap >
</ foo >
Note: the above solution assumes that the DTD defines foo to be a dictionary with two members "bar" and "zap", an integer named "bar" and a text string named "zap". Without such information, explicit typing, as below, is probably better.
< foo dt = "dictionary" >
<bar dt = "integerType"> 1 </ bar >
< zap dt = "textType" > stuff </ zap>
</ foo >
This solution raises the issue of whether there is a subtype associated with the dictionary data type to indicate the expected members or whether a member indicates this?
After some thinking about the DTD, I have concluded that there must be a separate DTD for each operation request and each operation response. With 10 operations, that means 20 DTDs. They can probably share some of common stuff.
Designing a DTD is an art like designing the grammar of a programming language. The more carefully the grammar is specified, the harder it is to read. I have opted to keep the DTD easy to read.
These example show some of the limitations of DTDs.
DTD for Get-Printer-Attributes request
The following is the DTD for Get-Printer-Attributes request for the encoding defined above.
<!DOCTYPE request [
<!ELEMENT request "(operation)">
<!ATTLIST request operation CDATA #FIXED "Get-Printer-Attributes"
version CDATA #REQUIRED
xml:lang CDATA #REQUIRED
request-id CDATA #IMPLIED >
<!ELEMENT operation "(printer-uri | requesting-user-name ? |
requested-attributes? | document-format? )+">
<!-- the syntax is unable to specify that element of an operation appears at most once but in any order -->
<!ELEMENT printer-uri "(#PCDATA)+">
<!ATTLIST printer-uri dt CDATA "uriType" >
<!ELEMENT requesting-user-name "(#PCDATA)+">
<!ATTLIST requesting-user-name xml:lang NMTOKEN #IMPLIED
dt CDATA "uriType" >
<!ELEMENT requested-attributes "item">
<!ELEMENT item "(ANY)+">
<!-- for requested-attributes ANY is restricted to #PCDATA which is an attribute name -->
<!ATTLIST item dt CDATA #IMPLIED >
<!-- the data type depends on the attribute containing the item -->
<!ELEMENT document-format "(#PCDATA)+">
<!ATTLIST document-format dt CDATA "mimeMediaType" >
]>
The above example defines much of what is allowed, but leaves some parts undefined.
DTD for Get-Printer-Attributes response
The following is the DTD for Get-Printer-Attributes response for the encoding above.
<!DOCTYPE response [
<!ELEMENT response "(operation , unsupported? , printer )">
<!ATTLIST response status-code CDATA #REQUIRED
version CDATA #REQUIRED
xml:lang CDATA #REQUIRED
request-id CDATA #IMPLIED >
<!ELEMENT operation "(status-message? )">
<!ELEMENT status-message "(#PCDATA)+">
<!ATTLIST status-message dt CDATA "textType" >
<!ELEMENT unsupported "(requesting-user-name | document-format)+">
<!ELEMENT requesting-user-name "(#PCDATA)+">
<!ATTLIST requesting-user-name dt CDATA "outOfBandType" >
<!ELEMENT document-format "(#PCDATA)+">
<!ATTLIST document-format dt CDATA #IMPLIED >
<!-- if the data type is unspecified, the value is an unsupported format -->
<!-- if the data type is specified at "outOfBand", the value should be "unsupported" -->
<!ELEMENT printer "(ANY)+">
<!-- or alternatively each printer attribute could be defined instead of "ANY" -->
<!ELEMENT printer "(job-priority-default | job-priority-supported |
job-hold-until-default | job-hold-until-supported | … )+">
<!-- where "…" represents the rest of the printer attributes -->
<!-- the attributes are defined below -->
<!ELEMENT job-priority-default "(#PCDATA)+">
<!ATTLIST job-priority-default dt CDATA "integerType" >
<!ELEMENT job-priority-supported "(#PCDATA)+">
<!ATTLIST job-priority- supported dt CDATA "integerType" >
<!ELEMENT job-hold-until-default "(#PCDATA)+">
<!ATTLIST job-hold-until-default dt CDATA "keywordType" >
<!--the alternate data type "nameType" must be explicit in the protocol -->
<!ELEMENT job-hold-until-supported "(#PCDATA)+">
<!ATTLIST job-hold-until-supported dt CDATA "setOf"
subtype CDATA "keywordType" >
<!-- add a "subtype" attribute to specify the subtype of the "setOf" – bad solution -->
]>
The DTD gets more difficult for the Unsupported attributes if it attempts to enumerate the attributes that can come back because each attribute now has values that would otherwise not validate.
DTD for IPP Using Schema from XML Data
The following two examples show a schema for the same request and response operation as shown for the DTD above. The schema rules come from the XML Data document referenced previously.
This schema does a better job than the DTD, but it still is not sufficient.
DTD for Get-Printer-Attributes request
The following is the DTD for Get-Printer-Attributes request for the case 1 encoding.
<s:schema id= "request" >
<elementType id="request">
<description>The root of the operation.</description>
<element type="#operation" occurs="REQUIRED"/>
<attribute id="operation" presence = "FIXED" default="Get-Printer-Attributes" />
<attribute id="version" presence = "REQUIRED" />
<attribute id="xml:lang" presence = "REQUIRED" dt="language" />
<attribute id="request-id" presence = "IMPLIED" dt="int" default="1" />
</elementType >
<elementType id="operation">
<description>Contains operation attributes.</description>
<group groupOrder="AND" occurs="REQUIRED">
<!-- the "AND" means that the group children can occur in any order -->
<element type="#printer-uri" occurs="REQUIRED"/>
<element type="#requesting-user-name" occurs="OPTIONAL"/>
<element type="#requested-attributes" occurs="OPTIONAL"/>
<element type="#document-format" occurs="OPTIONAL"/>
</group>
</elementType >
<elementType id="printer-uri">
<description>The target printer-uri.</description>
<string/>
<datatype dt="uriType" />
<attribute id="dt" presence = "OPTIONAL" default="uriType" />
</elementType >
<elementType id="requesting-user-name">
<description>The requesting user name.</description>
<string/>
<datatype dt="nameType" />
<attribute id="dt" presence = "OPTIONAL" default="nameType" />
<attribute id="xml:lang" presence = "OPTIONAL" default="languageType" />
</elementType >
<elementType id="requested-attributes">
<description>The attributes requested.</description>
<element type="#item" occurs="ONEORMORE"/>
</elementType >
<elementType id="item">
<!-- this definition of "item" supports only the setOf keywords which is sufficient here -->
<description>each element of the set.</description>
<string/>
<datatype dt="keywordType"/>
<attribute id="dt" presence = "OPTIONAL" default="keywordType" />
</elementType >
<elementType id="document-format">
<description>The document-format.</description>
<string/>
<datatype dt="mimeMediaType"/>
<attribute id="dt" presence = "OPTIONAL" default="mimeMediaType" />
</elementType >
</s:schema>
DTD for Get-Printer-Attributes response
The following is the DTD for Get-Printer-Attributes response for the case 1 encoding.
<s:schema id='response'>
<elementType id="response">
<description>The root of the operation.response</description>
<group occurs="REQUIRED">
<!-- the lack of a groupOrder attribute means that each child must be in the specified order -->
<element type="#operation" occurs="REQUIRED"/>
<element type="#unsupported" occurs="OPTIONAL"/>
<element type="#printer" occurs="REQUIRED"/>
</group>
<attribute id="status-code" presence = "REQUIRED" dt="int" />
<attribute id="version" presence = "REQUIRED" />
<attribute id="xml:lang" presence = "REQUIRED" dt="language" />
<attribute id="request-id" presence = "IMPLIED" dt="int" />
</elementType >
<elementType id="operation">
<description>Contains operation attributes.</description>
<element type="#status-message" occurs="OPTIONAL"/>
</elementType >
<elementType id="status-message">
<description>The status message.</description>
<string/>
<datatype dt="textType" />
<attribute id="dt" presence = "OPTIONAL" default="textType" />
<attribute id="xml:lang" presence = "OPTIONAL" default="languageType" />
</elementType >
<elementType id="unsupported">
<description>Contains unsupported operation attributes.</description>
<group groupOrder="AND" occurs="REQUIRED">
<!-- the "AND" means that the group children can occur in any order -->
<element type="#requesting-user-name" occurs="OPTIONAL"/>
<element type="#document-format" occurs="OPTIONAL"/>
</group>
</elementType >
<elementType id="requesting-user-name">
<description>The requesting-user-name.</description>
<string/>
<datatype dt="nameType"/>
<attribute id="dt" presence = "OPTIONAL" default="uriType" />
<attribute id="xml:lang" presence = "OPTIONAL" default="languageType" />
</elementType >
<elementType id="document-format">
<description>The document format.</description>
<string/>
<datatype dt="mimeMediaType"/>
<attribute id="dt" presence = "OPTIONAL" default="mimeMediaType" />
</elementType >
<elementType id="printer">
<description>Contains printer attributes.</description>
<any/>
<!-- Instead of "any", we could enumerate the attributes as we have above -->
</elementType >
<elementType id="job-priority-default">
<description>job priority.</description>
<string/>
<datatype dt="integerType"/>
<attribute id="dt" presence = "OPTIONAL" default="integerType" />
</elementType >
<elementType id="job-priority-supported">
<description>The job priority supported.</description>
<string/>
<datatype dt="integerType"/>
<attribute id="dt" presence = "OPTIONAL" default="integerType" />
</elementType >
<elementType id="job-hold-until-default">
<string/>
<datatype dt="keywordType"/>
<attribute id="dt" presence = "OPTIONAL" default="keywordType" />
</elementType >
<elementType id="job-hold-until-supported">
<string/>
<element type="#item" occurs="ONEORMORE"/>
<attribute id="dt" presence = "OPTIONAL" default="setOfType keywordType" />
</elementType >
<elementType id="item">
<description>each element of the set.</description>
<mixed/>
<!-- The value of "mixed" permits any element or "string". That is too vague -->
<attribute id="dt" presence = "OPTIONAL" />
</elementType >
</s:schema>
Protocol Examples with XML
These are the same examples that appear in the current IPP protocol document. I have added the target uri and requesting-user-name which never got added to the IPP protocol document.
The following is an example of a text/xml entity for Print-Job request with job-name, copies, and sides specified
<?XML version= "1.0" encoding= "US-ASCII">
< request operation= "Print-Job" version= "1.0" xml:lang= "en-US" request-id= "1">
<operation>
<printer-uri>killtree</printer-uri>
<requesting-user-name>rherriot</ requesting-user-name >
<job-name>foobar</job-name>
<copies>20</copies >
<sides>two-sided-long-edge</sides >
</operation>
</ request >
Print-Job Response (successful)
Here is an example of a Print-Job response that is successful.
<?XML version= "1.0" encoding= "US-ASCII">
< response status-code= "0" version= "1.0" xml:lang= "en-US" request-id= "1">
<operation>
<status-message>OK</status-message >
</operation>
<job>
<job-id>147</job-id>
<job-uri>http://foo/123</job-uri >
<job-state>3</job-state >
</job>
Here is an example of a Print-Job response that fails because the printer does not support sides and because the value 20 for copies is not supported:
<?XML version= "1.0" encoding= "US-ASCII">
< response status-code= "400" version= "1.0" xml:lang= "en-US" request-id= "1">
<operation>
<status-message>bad-request</status-message >
</operation>
<unsupported>
<job-k-octets>16777216</job-k-octets>
<copies>20</copies>
<sides dt="outOfBandType"> unsupported </sides>
</unsupported>
</ response >
The following is an example of Print-URI request with copies and job-name parameters.
<?XML version= "1.0" encoding= "US-ASCII">
< request operation= "Print-URI" version= "1.0" xml:lang= "en-US" request-id= "1">
<operation>
<printer-uri>killtree</printer-uri>
<requesting-user-name>rherriot</ requesting-user-name >
<document-uri>ftp://foo.com/foo</document-uri>
<job-name>foobar</job-name>
<copies>1</copies >
</operation>
</ request >
The following is an example of Create-Job request with no parameters and no attributes
<?XML version= "1.0" encoding= "US-ASCII">
< request operation= "Create-Job" version= "1.0" xml:lang= "en-US" request-id= "1">
<operation>
<printer-uri>killtree</printer-uri>
<requesting-user-name>rherriot</ requesting-user-name >
</operation>
</ request >
The following is an example of Get-Jobs request with parameters but no attributes.
<?XML version= "1.0" encoding= "US-ASCII">
< request operation= "Get-Jobs" version= "1.0" xml:lang= "en-US" request-id= "123">
<operation>
<printer-uri>killtree</printer-uri>
<requesting-user-name>rherriot</ requesting-user-name >
<limit>50</limit>
<requested-attributes>
<item>job-id</ item >
<item>job-name</ item >
<item>document-format </ item >
</requested-attributes>
</operation>
</ request >
The following is an of Get-Jobs response from previous request with 3 jobs. The Printer returns no information about the second job.
<?XML version= "1.0" encoding= "ISO-8859-1">
< response status = "0" version= "1.0" xml:lang= "en-US" request-id= "123">
<operation>
<status-message>OK</status-message>
</operation>
<job xml:lang = "fr-CA" >
<job-id>50</job-id>
<job-name>fou</job-name>
</job>
<job>
</job>
<job >
<job-id>148</job-id>
<job-name xml:lang = "de-CH" >isch guet</job-name>
</job>
</response>
Get-Printer-Attributes Request
The following is an example of Get-Printer-Attributes request. This example is not in the IPP protocol document.
<?XML version= "1.0" encoding= "UTF-8">
< request operation= "Get-Printer-Attributes" version= "1.0" xml:lang= "de" request-id= "15257">
<operation>
<printer-uri>morte-de-arbre</printer-uri>
<requesting-user-name>rherriot</ requesting-user-name >
<document-format>application/PostScript</document-format>
<requested-attributes>
<item>media-supported</ item >
<item>number-up-supported</ item >
<item>printer-state-message</ item >
<item>printer-state-reasons</ item >
<item>printer-location </ item >
</requested-attributes>
</operation>
</ request >
Get-Printer-Attributes Response
The following is an example of Get-Printer-Attributes request. This example is not in the IPP protocol document. It illustrates attributes will several types of values and different languages.
<?XML version= "1.0" encoding= "UTF-8">
< response status = "0" version= "1.0" xml:lang= "de" request-id= "15257">
<operation>
<status-message>OK</status-message>
</operation>
<printer>
< media-supported >
<item>A4</item>
<item>A3</item>
<item dt= "name" xml:lang = "fr" >papier jaune</item>
<item>B4</item>
</ media-supported >
< number-up-supported >
<item dt = "rangeOfInteger"><min>1</ min > <max>4</ max ></item>
<item>8</item>
<item>16</item>
</ number-up-supported >
< printer-state-reasons dt = "outOfBandType" > unknown </ printer-state-message >
< printer-state-message> kein Papier </ printer-state-message >
<printer-location xml:lang = "fr" > à côté de chambre 516</printer-location>
</printer>
</response>
Appendix A: Alternate Representation of Attributes
There are several ways to encode an Attribute. We will examine 4 possible ways:
Name |
Data type |
tag name |
none is specified if the data type is the one defined in the DTD; otherwise use the value of the attribute "dt" |
tag name |
value of the attribute "dt" |
tag name |
tag name |
value of the attribute "name" |
tag name |
The first way is the simplest and probably should be the one adopted.
The examples below use the following attributes:
Name |
Data Type |
priority |
integer |
sides |
keyword |
sides-default |
keyword |
sides-supported |
setOf keywords |
job-k-octets-supported |
rangeOfInteger |
media-supported |
setOf (keywords or names) |
An explanation of the four solutions follows:
<AttributeName > AttributeValue </AttributeName>
E.g.
< priority>50</priority>
< sides> one-sided </sides>
< sides-default> one-sided </ sides-default >
If the data type of an attribute value differs from that defined in the DTD, then its data type is specified by the XML "dt" attribute. The syntax is:
<AttributeName dt = "AttributeType" > AttributeValue </AttributeName>
E.g.
< priority dt = "outOfBandType" >unsupported</priority>
Note: that special markup, such as <unsupported> could be used in place of the explicit typing, but this solution requires that such markup names not clash with the markup used for structured values. The explicit data type seems like a simpler solution.
For attributes containing a set of values, each value is surrounded by the "item" tags, which act like parentheses to separate the values. The syntax is:
<AttributeName >
<item> AttributeValue </item>
...
<item> AttributeValue </item>
</AttributeName>
E.g.
< sides-supported >
<item> one-sided </item>
<item> two-sided-long-edge </item>
</ sides-supported >
If the data type of any item differs from that specified by the DTD, then its data type is specified by the XML "dt" attribute in the "item". The syntax is:
<AttributeName >
<item> AttributeValueWithDTDType </item>
...
<item dt= "AttributeType" > AttributeValueWithNonDTDType </item>
</AttributeName>
E.g.
< media-supported >
<item> letter </ item >
< item > legal </ item >
< item dt = "nameType" > fooPaper </ item >
</ media-supported >
<AttributeName dt=TypeName > AttributeValue </AttributeName>
E.g.
< priority dt = "integer"> 50</priority>
< priority dt = "outOfBandType" >unsupported</priority>
< sides dt = "keyword"> one-sided </sides>
< sides-default dt = "keyword"> one-sided </ sides-default >
For attributes with a set of values, the syntax is:
<AttributeName dt=setOf >
<item dt=TypeName > AttributeValue </item>
...
<item dt=TypeName > AttributeValue </item>
</AttributeName>
E.g.
< sides-supported dt="setOf" >
<item dt = "keyword"> one-sided </item>
<item dt = "keyword"> two-sided-long-edge </item>
</ sides-supported >
<AttributeName > TypedAttributeValue </attributeName>
The syntax for a non-structured and non-text TypedAttributeValue:
<AttributeType value = "AttributeValue"/ >
E.g.
< priority><integerType value = "50"/></priority>
< sides > <sidesType value = "one-sided"/></sides>
< sides-default > <sidesType value = "one-sided"/></sides>
The syntax for a text or structured TypedAttributeValue:
<AttributeType > AttributeValue </AttributeType >
Note: text values are handled differently from other non-structured values because an XML attribute value cannot contain both a single and double quote.
E.g.
< job-name > <nameType>my job</nameType></job-name>
< job-k-octets-supported >
< rangeOfIntegerType > <min>1</ min > <max>10000</ max > </ rangeOfIntegerType >
</ job-k-octets-supported >
For attributes with a set of values, the syntax is:
<AttributeName >
<setOf>
< AttributeType > AttributeValue </ AttributeType >
...
< AttributeType > AttributeValue </ AttributeType >
</setOf>
</AttributeName>
E.g.
< sides-supported >
< setOf >
<sidesType value = "one-sided">
<sidesType value = "two-sided-long-edge">
</ setOf >
</ sides-supported >
The syntax for a non-structured and non-text TypedAttributeValue:
<AttributeType name = AttributeName value = "AttributeValue" />
E.g.
<integerType name = "priority" value = "50"/>
<sidesType name = "sides" value = "one-sided"/>
<sidesType name = "sides-default" value = "one-sided"/>
The syntax for a text or structured TypedAttributeValue:
<AttributeType name = AttributeName > AttributeValue </AttributeType >
E.g.
<nameType name = "job-name" >my job</nameType >
< rangeOfIntegerType name = "job-k-octets-supported">
<min>1</ min > <max>10000</ max >
</ rangeOfIntegerType >
For attributes with a set of values, the syntax is:
<setOf name = "AttributeNam"e >
< AttributeType > AttributeValue </ AttributeType >
...
< AttributeType > AttributeValue </ AttributeType >
</setOf>
E.g.
< setOf name = "sides-supported" >
<sidesType value = "one-sided">
<sidesType value = "two-sided-long-edge">
</ setOf >
Appendix B: Alternate Representation of AttributeValues
The sections below give the encoding for each IPP data type using each of the 4 encoding described above. The syntax is explained with examples instead of a syntactic formalism. Examples with single values and with setOf values are shown for each data type unless there is no IPP attribute with a single value or a setOf value.
For each data type, example #1 is the one that is probably the best.
The following is the encoding of the attribute "job-state-message" with value "out of paper" and data type "textWithLanguage" in each of the 4 cases.
The "text" data type is encoding as above, but with "xml:lang" attribute omitted.
All other attributes of type "text" and "textWithLanguage" are encoded in a similar fashion.
There are no "setOf text" or "setOf textWithLanguage" values.
The value "out-of-paper" is a sample value of type "text". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The encoding is similar to text.
The following is the encoding of the attribute "job-name" with value "Mein Stoff" and type "nameWithLanguage" in each of the 4 cases.
The "name" data type is encoding as above, but with "xml:lang" attribute omitted.
All other attributes of type "name" and "nameWithLanguage" are encoded in a similar fashion.
There are no "setOf text" or "setOf textWithLanguage" values.
The value "Mein Stoff" is a sample value of type "name". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The following is the encoding of the attribute "charset-configured" with value "UTF-8" and type "charset" in each of the 4 cases.
All other attributes of type "charset" are encoded in a similar fashion except for the charset operation attribute, which uses the text value with no markup e.g.
<?XML version= "1.0" encoding= "UTF-8">
The following is the encoding of the attribute "charset-supported" with values "UTF-8" and "SJIS" and type "setOf charset" in each of the 4 cases.
All other attributes of type "setOf charset" are encoded in a similar fashion.
The value "UTF-8" is a sample value of type "charset". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The following is the encoding of the attribute "natural-language-configured" with value "en" and type "naturalLanguage" in each of the 4 cases.
All other attributes of type "naturalLanguage" are encoded in a similar fashion
The following is the encoding of the attribute "generated-natural-language-supported" with values "en" and "de" and with type "setOf naturalLanguage" in each of the 4 cases.
All other attributes of type "setOf naturalLanguage" are encoded in a similar fashion.
The value "en" is a sample value of type "naturalLanguage". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The following is the encoding of the attribute "document-format" with value "PostScript" and data type "mimeMediaType" in each of the 4 cases.
All other attributes of type "mimeMediaType" are encoded in a similar fashion
The following is the encoding of the attribute "document-format-supported" with values "PostScript" and "PCL" and data type "setOf mimeMediaType" in each of the 4 cases.
All other attributes of type "setOf mimeMediaType" are encoded in a similar fashion.
The value "PostScript" is a sample value of type "mimeMediaType". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The following is the encoding of the attribute "media" with value "letter" and data type "keyword" in each of the 4 cases.
All other attributes of type "keyword" are encoded in a similar fashion.
The following is the encoding of the charset attribute "media-supported" with keyword values "letter" and "legal" and a name value "fooPaper" in each of the 4 cases. This example illustrates an attributes with two types of values: keywords and names.
All other attributes of type "setOf keyword" are encoded in a similar fashion.
The value "letter" is a sample value of type "keyword". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The following is the encoding of the attribute "job-uri" with value "http:/foo/bar" and data type "uri" in each of the 4 cases.
All other attributes of type "uriType" are encoded in a similar fashion
The following is the encoding of the attribute "printer-uri-supported" with values "http:/foo/bar" and "http://foo/foo" and with data type "setOf uri" in each of the 4 cases.
All other attributes of type "uri" are encoded in a similar fashion.
The value "http:/foo/bar" is a sample value of type "uri". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The following is the encoding of the attribute "reference-uri-schemes-supported" with values "http" and "ftp" and with data type "setOf uriScheme" in each of the 4 cases.
All other attributes of type "uriScheme" are encoded in a similar fashion.
The value "http" is a sample value of type "uriScheme". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The encoding of boolean values could be done in several ways: "true"/"false", "t"/"f", "1"/"0", "yes"/"no" or "y"/"n". This example will use "1"/"0" ("1" is true and "0" is false), as in the XML Data standard.
The following is the encoding of the boolean attribute "color-supported" with value "1" in each of the 4 cases.
All other attributes of type "boolean" are encoded in a similar fashion
The value "1" is a sample value of type "boolean". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The following is the encoding of the attribute "priority" with value "50" and data type "integer" in each of the 4 cases.
All other attributes of type "integer" are encoded in a similar fashion.
The following is the encoding of the attribute "number-up-supported" with a "set Of" value of data type "integer" or "rangeOfInteger" in each of the 4 cases.
All other attributes of type "setOf integer" are encoded in a similar fashion.
The value "50" is a sample value of type "integer". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The following is the encoding of the attribute "orientation-requested " with value "2" and with data type "enum" in each of the 4 cases.
All other attributes of type "enum" are encoded in a similar fashion.
The following is the encoding of the attribute "finishings" with values "2" and "3" and with data type "setOf enum" in each of the 4 cases.
All other attributes of type "setOf enum" are encoded in a similar fashion.
The value "2" is a sample value of type "enum". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The encoding of dateTime values could be done in several ways:
Option 1 is probably the best choice and the one used in this example. Option 2 has too many variations, and option 3 is too verbose.
The following is the encoding of the attribute "printer-current-time" with value "1998-01-31T15:23:45,234-8:00" (from RFC1903 and ISO 8601) and of data type "dateTime" in each of the 4 cases.
All other attributes of type "dateTime" are encoded in a similar fashion.
The value "1998-01-31T15:23:45,234-8:00" is a sample value of data type "dateTime". Its encoding is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The encoding of resolution values could be done in several ways:
The following is the encoding of the attribute "printer-resolution" with value option 2 above and data type "resolution" in each of the 4 cases.
All other attributes of type "resolution" are encoded in a similar fashion
The following is the encoding of the attribute "printer-resolution-supported" with values as in option 2 and of data type "setOf resolution" in each of the 4 cases.
All other attributes of type "setOf resolution" are encoded in a similar fashion.
The value above is a sample value of type "resolution". The encoding of each element is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The encoding of rangeOfInteger values could be done in several ways:
The following is the encoding of the attribute "job-k-octets-supported " with value of option 2 and of data type "rangeOfInteger" in each of the 4 cases.
All other attributes of type "rangeOfInteger" are encoded in a similar fashion
The following is the encoding of the attribute "page-ranges" with values "letter" and "legal" and with data type "setOf rangeOfInteger" in each of the 4 cases.
All other attributes of type "setOf rangeOfInteger" are encoded in a similar fashion.
The value above is a sample value of type "rangeOfInteger". The encoding of each element is specified by the "encoding" attribute at the beginning of the entity. Any occurrences of "<" and "&" are replaced by "<" and "&" respectively.
The SetOf data type has been demonstrated in previous sections for each data type contained in a SetOf.
The encoding of outOfBand values could be done either with
The "outOfBand" data type is best for all of the encodings. The empty element tags could be used for the first "implicit" encoding, but it would be necessary that all tags used in values be unique so that tags from structured values wouldn’t clash with tags for outOfBand values.
The following is the encoding of the attribute "printer-resolution" with value option 2 above and with a data type of "outOfBand" in each of the 4 cases.
The following is the encoding of the attribute "finishings" with values "2" and "novalue" in each of the 4 cases. This example is probably artificial because, a printer would probably not return a setOf with a mix of outOfBand values and normal values.
The following is the encoding of a future dictionary attribute "foo" with a value of data type "dictionary" in each of the 4 cases.
This solution raises the issue of whether there is a subtype associated with the dictionary data type to indicate the expected members or whether a member indicates this?