WITSML API Documentación
WITSML API Documentación
VERSION v1.4.0
Document Information
DOCUMENT VERSION: 1.4.0 draft e
DATE: November 12, 2008
Technical Color: R:210, G:124, B:50
Language US English
Energistics™, POSC®, Epicentre®, WITSML™, PRODML™, Upstream Standards. Bottom Line Results.™,
The Energy Standards Resource Centre™ and their logos are trademarks or registered trademarks of
Energistics. Access, receipt, and/or use of these documents and all Energistics materials are generally
available to the public and are specifically governed by the Energistics Product Licensing Agreement
(http://www.energistics.org/posc/Product_License_Agreement.asp)
Page 2 of 147
WITSML Application Programming Interface
Amendment History
Version Date Comment By
1.4.0 12 November Changed the document name to remove “Core”. Gary
2008 Removed the term core from all references to the Masters
API.
Reformatted to new Energistics template.
Section “1 Introduction” moved to the “Executive
Summary”.
Section “2 Document Revisions” moved to this
“Amendment History”.
Section “3 Terminology and Basic Concepts” was
renumbered to “2 Terminology and Basic
Concepts”.
Section “4 API Objectives and Constraints”
moved to section “1 Introduction”.
Section “5 Use Cases” moved to subsection “1.1
Scope”.
The sections beginning with “6 The Interfaces”
were renumbered such that section “6” became
section “3”.
Added the following subsections:
o 1.2 Document Structure
o 1.3 Intended Audiences
o 1.4 Usage, Intellectual Property Rights,
and Copyright
o 1.6 References
o “1.7 Conventions
o 1.8 Motivation
o 1.9 History
o 1.10 Future Plans
All examples are now in a courier font.
Almost all newlines used to create space
between paragraphs have been eliminated.
Added figure captions.
Corrected misspellings.
Page 3 of 147
WITSML Application Programming Interface
1.4.0d 3 November Issue 1.3.1-108 “log object and index curve values” Gary
2008 In section “STORE and PUBLISH behavior”, modified Masters
bullet 2.b to indicate that the structural range must
match the data range.
Issue 1.3.1-88 “dTim behavior in realtime”
In section “WMLS_GetFromStore”, modified note 14
to indicate that a value of dTimLastChange requests
realtime only data which has changed since that time.
1.4.0rc 30 July 2008 Issue 1.2-155 “Define optionsIn for optional cascaded Gary
deletes” Masters
Added “cascadedDelete” as an OptionsIn for section
“WMLS_DeleteFromStore” and modified “Note
#2”.Added error code -207 to section “Return Values”.
Deleted comment about referential integrity in section
“APPENDIX A”.
Issue 1.3.1-5 “WMLS_UpdateInStore behavior”
In section “Unique Identifiers (UID's)”, changed
“should” to “recommended” for globally unique uids
and added a table to summarize the Store uid
optionality requirements. In section
“WMLS_AddToStore”, documented that parentage
uid values are also required. In section
“WMLS_DeleteFromStore”, documented that QueryIn
does not conform to a schema. In section
“WMLS_UpdateInStore,” documented that the XMLin
parameter must conform to an update schema
variant. In section “WMLS_GetFromStore”, clarified
that QueryIn is not schema compliant.
Issue 1.3.1-54 “UpdateInStore and structural range”
In sections “APPENDIX D” and “STORE and
PUBLISH behavior”, documented that “append”
means to add new data whose index is greater than
the current maximum index. In section “STORE and
PUBLISH behavior”, clarify than a “replace” is
logically an “insert” if no data exists within the
specified range. In section “Return Values”, added
error codes -208 and -209.
Issue 1.3.1-96 “WITSML API 1.4a Draft
Documentation Issue”
In section “Choosing an Interface”, deleted the
paragraphs on “changed data”.
Issue 1.3.1-98 “Response to WITSML Version 1.4.0
Release Candidate”,
In section “Querying for Rows in a Systematically
Growing Object”, changed the returned
dataRowCount from 3 to 5. In section “APPENDIX B -
Unit of Measure”, add a subsection on default units.
Page 4 of 147
WITSML Application Programming Interface
1.4.0c 30 July 2008 Issue 1.3.1-102 “Response to WITSML Version 1.4.0 Gary
continu Release Candidate” Masters
ed In section “WMLS_AddToStore”, made some minor
clarifications on the realtime behavior and added
commonData to example. In section “#APPENDIX A -
Example Data Object Schema”, added commonData
to examples. In section “WMLS_UpdateInStore”,
eliminated the delete functionality. In section
”WMLS_DeleteFromStore”, added the delete
functionality from the update section, added the
capability of deleting non-containers using an empty
element or attribute, added note to look at growing-
object behavior and added comment on deleting sub-
nodes only requiring user update rights. In sections
“STORE and PUBLISH behavior”, “Deleting Rows in
a Systematically Growing Object” and “Deleting
Columns in a Systematically Growing Object”.
deleted now-invalid sentence about "normal behavior
that only an object can be deleted”. In several spots,
clarified that delete from store an also delete subset.
Issue 1.3.1-105 “Comments about WITSML version
1.4.0”
In section “Combining Data Item and Object
Selection”, documented the possibility of “greater
than” comparisons instead of “greater than or equal
to”.
Issue 1.3.1-107 “Clarification required for WitsML-
v1.3.1.1 log indexType”
In section “log Data Object Example”, eliminated
explicit example values for indexType. Used a valid
value for the example.
Page 5 of 147
WITSML Application Programming Interface
1.4.0a 14 July 2008 Changed all version references from “1.3.1” to Gary
“1.4.0”. Changed all namespace designations from Masters
“130” to “140” (including “140ex”).
Changed POSC to Energistics.
In section ”Sensor Data over WITSML”, fixed
example which had mnemonic as an attribute.
Issue 1.2-153 “Must document semantics of Get,
Add, Update and Delete for realtime”
Added a note to WMLS_DeleteFromStore that allows
deletion from realtime based on natural key match..
Documented that WMLS_UpdateInStore can update
realtime based on natural keys.
Issue 1.3-60 “6.3.1 Case Sensitivity- WISTSML 1.3.1
spec”
Documented in section “Case Sensitivity” that uids
are case sensitive in queries.
Issue 1.3.1-1 “What does "empty object" mean?”
Issue 1.3.1-19 “Query Start/End indexes special
handling (trajectory, mudlog)”
Added note to section “WMLS_GetFromStore” to
document that all criteria must be met or nothing will
be returned. Modified sections “STORE and
PUBLISH behavior”, “trajectory Data Object
Example”, “mudLog Data Object Example” and
“Querying for Rows in a Systematically Growing
Object“ to document that if no data is found in a
selection range then “nothing will be returned
because not all criteria will have been met” (i.e.,
eliminated statements that only header or empty
object will be returned).
Issue 1.3.1-5 “WMLS_UpdateInStore behavior”
Added notes to WMLS_UpdateInStore to clarify the
behavior. This changes the behavior for recurring
containers without a uid from ”insert and delete” to
“insert only”. Documented that the XMLin should
conform to a derived “read” schema where everything
is optional (same for WMLS_DeleteFromStore and
WMLS_GetFromStore – write schema for
WMLS_AddToStore). Documented that the result of
the update should conform to the “write” schema.
Issue 1.3.1-29 “Minor error in the WITSML API
documentation”
In section “Querying for Rows in a Systematically
Growing Object” changed the return value of
dataRowCount from 5 to 3.
Issue 1.3.1-40 “Getting Permission”
In section “Return Values”, added error code 206.
Issue 1.3.1-49 “Realtime Behavior”
Documented a note in section “WMLS_AddToStore
that the realtime object can be accessed via the store
interface using natural keys and that only the most
recent data will be retained
Page 6 of 147
WITSML Application Programming Interface
1.4.0a 14 July 2008 Issue 1.3.1-52 “Max # of log curve points returned” Gary
continu In section “WMLS_GetFromStore”, added to note 12. Masters
ed
Issue 1.3.1-58 “Minimum number of objects in a
WITSML document”
Documented that the XMLout from
“WMLS_GetFromStore” should conform to a derived
“read” schema where all elements and attributes are
optional. Deleted note 13.c. Added note that the
QueryIn template will not be schema compliant if it
contains empty values but should be compliant with
read schema if no empty values are used. In section
“Process interaction with ‘uom’”, did not remove “or
absent” because absent just means that the client did
not request a unit in which case the server returns the
value in a default unit.
Issue 1.3.1-63 “Detection of new data objects”
In section “Combining Data Item and Object
Selection”, documented the possibility of “greater
than or equal to” comparisons.
Issue 1.3.1-67 “Data quality and consistency”
In the section “Responsibilities” of the unit appendix,
documented that a unit can change.
Issue 1.3.1-75 “Change-detection behavior”
Added element objectGrowing to mudLog, log and
trajectory in section “APPENDIX A - Example Data
Object Schema”.
Inserted new “Appendix D: Special Handling of
Change Information” which incremented the letter
and numbering of the subsequent appendixes.
Changed the name of “Appendix D: Special Handling”
to “Appendix E: Special Handling of Growing
Objects”.
Issue 1.3.1-79 “abstractString and
abstractUncollapsedString do not handle a empty
string”
Assumed that this issue modified the agreement in
Issue 1.3.1-5 by eliminating any options which are not
“read” schema compliant (i.e., empty values for
attributes or non-container elements). Documented
that XMLin in WMLS_UpdateInStore must be “read”
schema compliant.
Issue 1.3.1-82 “WITSML Compression”
Documented a compression-method OptionsIn (with
a value of "gzip" or :”none”) in WMLS_AddToStore,
WMLS_GetFromStore, WMLS_UpdateInStore. Also
added a compression-direction OptionsIn (with a
value of "request", "response", "both") in
WMLS_GetFromStore. Defaulted to "response" for
Get. In section “Return Values“, defined an error code
for a requested compression option not supported.
Page 7 of 147
WITSML Application Programming Interface
Page 8 of 147
WITSML Application Programming Interface
Table of Contents
Executive Summary 13
1. Introduction 14
1.1 Scope 14
1.1.1 Sensor Data over WITSML 14
1.1.2 Rig Site Repository/Aggregator 18
1.2 Document Structure 20
1.3 Intended Audiences 21
1.4 Usage, Intellectual Property Rights, and Copyright 21
1.5 Terminology and Definitions 22
1.6 References 22
1.7 Conventions 22
1.8 Motivation 23
1.9 History 23
1.10 Future Plans 23
2. Terminology and Basic Concepts 24
2.1 WITSML] Object or Data Object 24
2.2 Unique Identifiers (UIDs) 25
2.3 Representation versus Transport 26
2.4 Transport versus Storage 26
2.5 [WITSML] Document 26
2.6 Subscribe/Publish Application Program Interface (API) 26
2.7 Client/Server Application Program Interface (API) 26
2.8 Versioning 27
2.8.1 Versioning - API Signature 27
2.8.2 Versioning - API Capabilities 28
2.8.3 Versioning - Executable Programs 28
2.8.4 Incrementing Version Numbers 28
3. The Interfaces 29
3.1 STORE and PUBLISH 29
3.2 Choosing an Interface 29
3.3 Common Behavior 30
3.3.1 Case Sensitivity 30
3.3.2 Query and Subscription Templates 31
4. STORE Interface 32
4.1 Introduction 32
4.2 Query Templates 34
4.2.1 Introduction 34
4.2.2 Data Item Selection 35
4.2.3 Object Selection 36
4.2.4 Combining Data Item and Object Selection 37
4.2.5 Selection using Recurring Data Items 38
4.2.6 Minimum Query Template 40
4.3 Authentication and Encryption 40
4.4 Capabilities Objects 41
4.4.1 Client Capabilities (capClient) Object 41
4.4.2 Server Capabilities (capServer) Object 41
4.4.3 Capabilities by Object 42
4.5 STORE Functions 45
4.5.1 WMLS_AddToStore 46
4.5.2 WMLS_DeleteFromStore 48
4.5.3 WMLS_GetBaseMsg 52
Page 9 of 147
WITSML Application Programming Interface
4.5.4 WMLS_GetCap 53
4.5.5 WMLS_GetFromStore 54
4.5.6 WMLS_GetVersion 57
4.5.7 WMLS_UpdateInStore 58
4.6 STORE Interface - WSDL File 62
4.6.1 File Listing 63
4.6.2 Narrative 68
5. PUBLISH Interface 70
5.1 Introduction 70
5.2 Subscription Requests 73
5.2.1 action attribute - the action being requested 75
5.2.1.1 action=”add” - add a new subscription 75
5.2.1.2 action=”modify” - modify an existing subscription 76
5.2.1.3 action=”cancel” - cancel one or all existing subscriptions 77
5.2.1.4 action=”verify” - verify an existing Subscription 78
5.2.1.5 action=”retransmit” - retransmit the realtime headers 79
5.2.2 retCode attribute - the return code 79
5.2.3 idSub attribute - the subscription identifier 80
5.2.4 test attribute - test network connectivity 80
5.2.5 host, process, port and encrypt attributes - specify the subscriber’s URL 81
5.2.6 idPub attribute - identify the Publisher 82
5.2.7 retry attribute - the error retry count 82
5.2.8 updateInterval attribute - limit the publication rate 83
5.2.9 Subscription Object Attribute Summary 84
5.3 Subscription Templates 85
5.3.1 Realtime Example 88
5.4 Publishing and Maintaining Subscriptions 91
5.5 POST Request 92
5.5.1 Syntax 92
5.5.2 Notes: 93
5.5.3 Example: 93
5.6 Authentication and Encryption 93
5.7 Capabilities Objects 94
5.7.1 Subscriber Capabilities (capSubscriber) Object 94
5.7.2 Publisher Capabilities (capPublisher) Object 94
5.7.3 Capabilities by Object 95
5.8 PUBLISH Functions 98
5.8.1 WMLP_GetBaseMsg 98
5.8.2 WMLP_GetCap 99
5.8.3 WMLP_GetVersion 100
5.8.4 WMLP_Subscribe 101
5.9 PUBLISH Interface - WSDL File 102
5.9.1 File Listing 103
5.9.2 Narrative 106
6. APPENDIX A - Example Data Object Schema 108
7. APPENDIX B - Unit of Measure 113
7.1 Overview 113
7.2 Basics 113
7.3 Process interaction with ‘uom’ 114
7.4 Server defaults 114
7.5 Responsibilities 115
7.6 Updating 115
8. APPENDIX C - Defined Values 116
8.1 Return Values 116
9. APPENDIX D – Special Handling of Change Information 118
10. APPENDIX E – Special Handling of Growing Objects 120
Page 10 of 147
WITSML Application Programming Interface
Page 11 of 147
WITSML Application Programming Interface
Executive Summary
This document describes the components of the WITSML Version 1.4.0 Application Programming Interface
(API). These components consist of the Client/Server and Subscribe/Publish interfaces.
Page 12 of 147
WITSML Application Programming Interface
1. Introduction
The WITSML API is intended to be platform independent. It should be useable by any programming language
that can invoke a function-call interface. An object-oriented language is not required, although object-oriented
wrappers over the WITSML API could be developed.
The API is specified in function-call syntax, and specifies simple data types (integers, strings, etc) for
parameters and return values. Pointers and structures are not used.
Unless noted otherwise, function calls are synchronous (blocking).
The concurrent use of API functions by multiple client applications is dependent on the particular API
implementation.
This specification describes only the external interfaces exposed by the API, not any particular
implementation. The internal implementation of the API can and will vary. All references in this document to
implementation scenarios are for the purpose of example only.
1.1 Scope
The following use cases are intended to illustrate how the two API interfaces - Client/Server and
Subscribe/Publish - might be used. The use cases do not necessarily illustrate recommended solutions to
specific business requirements.
1.1.1 Sensor Data over WITSML
This example illustrates how WITSML realtime data objects could be transferred using the Subscribe/Publish
mode from a sensor aggregator application on a rig to an application in the operating company’s offices.
The sensor aggregator system is the Publisher and the office system is the Subscriber. The realtime data
objects are “pushed” from the Publisher to the Subscriber.
The first phase in the process involves “subscribing” to one or more of the Publisher’s available realtime data
channels. To do this, the potential Subscriber sends a subscription request to the Publisher. The subscription
request will specify, among other things, that the Subscriber wishes to receive the WITSML realtime data
object and which channels of the realtime object.
In order to know what data object types and realtime channels it can request, the Subscriber can first ask the
Publisher for that information.
The Subscriber can determine what data object types are available by using SOAP to invoke the Publisher’s
WMLP_GetCap (Get Capabilities) function, denoted by (1) in the diagram below.
Page 13 of 147
WITSML Application Programming Interface
SUBSCRIBING
Publisher Subscriber
WMLP_GetCap
1
sensor Publisher Capabilities Object
2
WMLS_GetFromStore 3
sensor
sensor aggregator Available Channels
4 office
application application
WMLP_Subscribe
(and send Subscriber
sensor
Capabilities Object)
5
Subscription Identifier
7 6
Subscriptions
Storesection
"ines used
to create
Figure 1: Subscribing Scenario
space
between function returns the Publisher’s Capabilities object (2) to the Subscriber,
The Publisher's WMLP_GetCap
paragraphs
which lists the data object types the Publisher can provide. In this example, the Publisher would list only the
have
realtime data object type been
in the returned Capabilities object, as that is the only data object type it can publish.
eliminated.
The Subscriber then needs to know what channels are available for the realtime object. This information is
not conveyed in the Publisher's Capabilities object, since it can vary by well, wellbore or time. Instead, the
Subscriber can query the Publisher for this information (3), using the WMLS_GetFromStore function. For
example, the following query would return the channel mnemonics and well/wellbore identifiers for all realtime
objects on the Publisher (4).
<realtimes xmlns="http://www.witsml.org/schemas/140ex">
<realtime uidWell="" uidWellbore="">
<channel>
<mnemonic />
</channel>
</realtime>
</realtimes>
If the Subscriber already knew the well/wellbore identifiers, it could have specified them in the query:
<realtimes xmlns="http://www.witsml.org/schemas/140ex">
<realtime uidWell="w1" uidWellbore="w1b">
<channel>
<mnemonic />
</channel>
</realtime>
</realtimes>
This could result in a smaller result set and a quicker, more efficient query.
Page 14 of 147
WITSML Application Programming Interface
Note
Notice that we said the Subscriber invoked the "Publisher's" WMLS_GetFromStore function.
But WMLS_GetFromStore is a STORE interface function, not a Publisher function.
What's going on here?
The answer is that in order to allow potential Subscribers the ability to dynamically
determine what data object instances (not merely the object types) that are available for
subscription, a Publisher must implement a part of the STORE interface; it must be both a
Publisher and a Server. However, in this case, it is not necessary for the Publisher system
to implement all the STORE interface functions, but only the WMLS_GetFromStore function.
It can then indicate its limited implementation by including only the WMLS_GetFromStore
function in the capServer object it provides to Client systems.
Once the Subscriber has determined which channels on which wells and wellbores are available to be
published, it then invokes the Publisher’s WMLP_Subscribe function (5) and subscribes to one or more
realtime channels. Included in the Subscription request (which is itself passed as a WITSML data object) are
the Subscriber’s host name and various other information that the Publisher will need when it has data to
send to the Subscriber. The Subscriber also passes its own Capabilities object to the Publisher. 1 Thus, both
the Publisher and Subscriber now know each other’s capabilities.
So that subscriptions are not lost across restarts of the Publisher system, the Publisher then records the
subscription in a non-volatile store (7) and returns a unique subscription identifier to the Subscriber (6). The
Subscriber can later use this subscription identifier to cancel, modify or verify the subscription.
Once the subscription has been accepted, we are then ready for the second phase of the process: publishing
the data.
Whenever new or changed data for the specified channels become available – perhaps immediately after the
subscription was received or at some time later - the sensor aggregator application will create a WITSML
realtime data object and send it to all Subscribers who are subscribed to that channel of the realtime data
object.
The sensor aggregator application is responsible for parsing the data coming in from the sensors, associating
that data to the appropriate data items defined for the WITSML realtime data object, supplying any missing
data items and creating the WITSML realtime data objects.
The sensor aggregator application then uses HTTP/S POST to send the WITSML data objects to the
Subscriber, as denoted by (2) in the diagram on the next page.
1
for example, the Subscriber will convey in its capabilities object the version of the API that it implements. This will allow new versions
Page 15 of 147
WITSML Application Programming Interface
PUBLISHING
Publisher Subscriber
sensor
2
Subscriber Process
sensor aggregator
application
1
4
sensor WMLI
Implementation
Proprietary
Data Store
While this use case illustrated using the Subscribe/Publish API to transport the WITSML
realtime data (notification) object, it’s important to note that the Subscribe/Publish API is
used to issue notifications of changes to any of the WITSML data object types. For
example, a Subscriber can request that a Publisher send it notifications of any new or
changed well objects. Although suited for use in situations where new transient data is
periodically available - such as with the realtime object - the Subscribe/Publish API is not
restricted to use for only the realtime data object.
2
because HTTP/S is used to transport the published data, this use case shows the Subscriber process running under a generic HTTP/S
Server (aka, “web server”). A Subscriber is free to implement its own dedicated, embedded HTTP/S processing if it wishes.
Page 16 of 147
WITSML Application Programming Interface
drilling
sensor management
application
data analysis
sensor application
sensor aggregator
application
On-Request
via
sensor
SOAP
REALTIME On-Request
objects via
Web Server
via SOAP
HTTP
POST
Subscriber WMLS
Process Implementation
Proprietary
Data Store
Page 17 of 147
WITSML Application Programming Interface
But in this case, we show the Subscriber process invoking the STORE interface instead. Since the STORE
interface must be implemented on this server anyway (to provide access for clients), it makes sense to use
this same implementation to store the realtime data received by the Subscriber process. This would assume
that log data is being stored – not realtime data.
There are typically different implementation considerations for storing large volumes of data – particularly if
received in “realtime” mode - versus supporting relatively lower volume transactional updates or queries. In
order to maintain good performance in both modes, the fairly static and low volume data objects such as well,
rig and wellbore might be stored by the STORE implementation in one database while the realtime data
objects received from the sensor application might be stored as logs in a different database, using a different
storage mechanism. But client applications are not aware of this; they merely request STORE to access a
particular object, regardless of how it is stored.
WMLS
Implementation
Page 18 of 147
WITSML Application Programming Interface
Orientation
Specification Application
Programming Interface Client
Server
Data Schema
Reference
Training
Documents Code
Page 19 of 147
WITSML Application Programming Interface
IT Director
Enterprise Architect
Data Architect
Drilling Engineer
Application Manager
USE KEY
A= PRIMARY DOCUMENT
Key document to read
B=SECONDARY DOCUMENT
Good material to review
C= LESS USEFUL
Review as needed
DOCUMENTATION
Page 20 of 147
WITSML Application Programming Interface
Term Definition
API Application Programming Interface. Within this document, this refers
to web services.
SOAP Simple Object Access Protocol
WITSML Wellsite Information Transfer Standard ML
WMLP A contraction of “WITSML Publish”.
WMLS A contraction of “WITSML Store”.
XML Extensible Markup Language
1.6 References
Table 2: References
1.7 Conventions
This section describes the use of key terms, notations, and abbreviations in this document.
THIS DOCUMENT DOES NOT CURENTLY CONFORM TO THESE CONVENTIONS.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT",
"RECOMMENDED", "MAY" and "OPTIONAL" in this document are to be interpreted as described in RFC
2119. (http://www.ietf.org/rfc/rfc2119.txt)
Text in a Grey underlined typeface represents a hyperlink
Text in Green highlights a statement that defines something that is included in scope.
Text in Red highlights a statement that defines something that is excluded from scope.
Page 21 of 147
WITSML Application Programming Interface
Text in italic blue represents information about concepts and facilities that might appear in a future version of
this material
1.8 Motivation
A primary focus for the changes in this version was to enhance support of automated workflows. The addition
of “APPENDIX D – Special Handling of Change Information” was a direct result of this effort. Another result
was clarification of STORE handling of realtime data. Most other changes represent a continual tightening of
the specifications.
1.9 History
WITSML was initially developed by the WITSML project, an oil industry initiative sponsored by BP and Statoil,
and later by Shell, as a new standard for drilling information transfer. Initial participation was from the major
service companies Baker Hughes, GeoQuest, Halliburton, Landmark and Schlumberger. As of the completion
of WITSML V1.2 in March 2003, POSC (now called Energistics) accepted custody of WITSML and is
managing the support and future evolution of WITSML through the WITSML Special Interest Group.
WITSML was designed to be a more modern alternative to WITS (Wellsite Information Transfer Standard)
and some of the original semantic content of the Data Schemas was derived from the WITS specification.
The most recent previous version of this specification was v1.3.1 which was released in December 2005.
Page 22 of 147
WITSML Application Programming Interface
well
wellbore
Page 23 of 147
WITSML Application Programming Interface
Get From Store Add To Store Update In Store Delete From Store
Result Request Request Request
object uid optional optional required required
parentage uid optional required required required
child uid optional required required optional
Page 24 of 147
WITSML Application Programming Interface
We will use the term "HTTP" in this document to specify "Hypertext Transport Protocol (un-
encrypted)".
We will use the term "HTTPS" to specify "Hypertext Transport Protocol over Secure Sockets
Layer (encrypted)"
We will use the term "HTTP/S" when generically referring to both HTTP and HTTPS.
Page 25 of 147
WITSML Application Programming Interface
2.8 Versioning
There are four major entities in the WITSML specification that can be "versioned":
the data objects
the API signature
the API capabilities
the executable programs
Each of these four entities use versioning in slightly different contexts:
Versioning - Data Objects
For a data object, the version number specifies the version of the XML Data Schema against which the object
can be validated. The number is conveyed in the version attribute of the data object's plural container
element:
<wells version="1.4.0.0" … >
<well … />
</wells>
The example indicates that the well object is compliant with the WITSML 1.4.0.0 XML Data Schemas.
A client or subscriber can also determine the version of WITSML data supported by the
server via WMLS_GetVersion.
Page 26 of 147
WITSML Application Programming Interface
Page 27 of 147
WITSML Application Programming Interface
3. The Interfaces
3.1 STORE and PUBLISH
The WITSML API defines two interfaces:
STORE (aka, Client/Server or WMLS)
PUBLISH (aka, Subscribe/Publish or WMLP)
The STORE interface provides Client applications access to WITSML data objects stored on a Server.
The PUBLISH interface provides Subscriber applications the ability to query a Publisher for what WITSML
data object types are available for publication, to subscribe to changes to data objects to be published at
some time in the future and to maintain the subscription requests held by the Publisher.
Both the STORE and PUBLISH interfaces are exposed to client applications via SOAP (Remote Procedure
Call-style).
Page 28 of 147
WITSML Application Programming Interface
Page 29 of 147
WITSML Application Programming Interface
CONCEPTS
Notice that no other attributes or child elements of the well element were returned in our example,
even those that might be defined as “required” by the WITSML schemas. If an attribute/element isn’t
explicitly requested in the Template, it will not be present in the returned objects.
If the client/subscriber requires a valid XML document be returned, it must explicitly include all
schema-mandatory attributes and elements in the query template.
Since a Template is permitted to omit required elements/attributes of a data object, a Template
cannot (typically) be validated against the WITSML schemas. A Template is a well-formed XML
document, but not necessarily a valid XML document.
Although the Query and Subscription Templates are almost identical in concept, they have minor differences
in their usage, and so we’ll discuss them individually in the STORE and PUBLISH interfaces.
Page 30 of 147
WITSML Application Programming Interface
4. STORE Interface
4.1 Introduction
The STORE interface provides Client applications the ability to:
add a WITSML data object to a Server
update an existing WITSML data object on a Server
delete an existing WITSML data object (or a subset) on a Server
query (retrieve) one or more existing WITSML data objects from a Server
When using the STORE interface, the transfer of WITSML data objects between client and server
is initiated by the client. The client application issues the request to access the stored objects - or
to a add new one - and the server immediately (synchronously) responds to the request.
The WITSML data objects are exchanged between client and server as XML documents.
The functions (methods) exposed by the STORE interface are prefixed with “WMLS_”.
The WMLS_ functions are exposed to client applications via SOAP (Remote Procedure Call-
style). A standardized Web Services Description Language (WSDL) file is used to define the
STORE interface exposed via SOAP.
CONCEPT
Although the WITSML client applications use the STORE interface to access the server as if
the various WITSML objects were stored as XML documents…there is no requirement for
the STORE implementation to internally persist the data as XML.
The client application hands-over to STORE one WITSML object in the form of an XML
document, and can later retrieve one or more objects in the form of an XML document.
The persistence mechanism used internally by the STORE implementation is not specified,
and the client application must not assume any particular storage mechanism, such as flat files
or a relational database. The only data format exchanged between the STORE implementation
and the client application are XML text documents.
Page 31 of 147
WITSML Application Programming Interface
To retrieve a WITSML data object stored on a server, the client application passes the type of
WITSML object and a Query Template as parameters to the WMLS_GetFromStore function:
RetVal = WMLS_GetFromStore(‘well‘, ç data object type
‘<wells…><well uid=“123”><name/></well></wells>‘,ç Query Template
OptionsIn,
CapabilitiesIn,
XMLout, ç returned objects
SuppMsgOut)
The server’s STORE implementation returns an XML document containing the WITSML object(s)
which satisfy the Query Template, and a return value (RetVal) indicating the success or failure of
the function.
► Query Templates are described in the next topic.
The client application can also add a single WITSML data object to a server by passing an XML
document containing the object to the WMLS_AddToStore function:
RetVal = WMLS_AddToStore("well", StringContainingXML)
And likewise, the client application can update or delete a single WITSML data object stored on
the server using the WMLS_UpdateInStore and WMLS_DeleteFromStore functions.
RESTRICTION
The WMLS functions exposed by the STORE interface all specify a single WITSML data object type
(well, rig, etc) in their data object type parameter. While some of the STORE interface functions allow
multiple occurrences of the same data object type to be manipulated in one invocation, none allow the
mixing of multiple data object types. And thus, the XML documents transported by the STORE
functions - both the data objects and the Query Templates described next - may contain multiple
occurrences of a single data object type, but not multiple data object types.
Page 32 of 147
WITSML Application Programming Interface
4.2.1 Introduction
The various STORE functions accept a Query Template as an input parameter.
In the example in the previous section, the second parameter is the Query Template. Here we
have restructured that example Query Template parameter so that the nesting of the XML
elements is more apparent: 3
<wells xmlns="http://www.witsml.org/schemas/140ex">
the Query <well uid=”123”>
<nameLegal/> the query
Template
</well>
</wells>
This Query Template contains only one query, which requests the legal name of the well object
that has an ID of “123”.
All Query Templates must contain a plural container element; in this case, “<wells>”.
Within the plural container element can be one or more singular elements of the same data
object type; in this case, “<well>”.
The Query Template could have included more than one query:
<wells xmlns="http://www.witsml.org/schemas/140ex">
<well uid=”123”>
<nameLegal/> 1st query
</well>
<well uid=”456”>
<nameLegal/> 2nd query
</well>
</wells>
Each <well> element in this Query Template is a separate query. Multiple queries can only be
specified when retrieving data.
The ability to submit multiple queries for the same data object type is provided merely for
efficiency – there is otherwise no relationship between the queries. Each is a separate,
standalone query that will result in zero or more well data objects being selected for each.
The data object(s) selected by multiple queries will be returned as separate data objects in one
plural container. The data object(s) resulting from query 1 (if any) will be first, followed by the data
object(s) resulting from query 2, and so on.
The returned data objects will not be explicitly identified with the query that requested them.
When using multiple queries, it is the responsibility of the client to determine which data object(s)
were returned as a result of which query, if such a correlation is necessary.
3
XML is not sensitive to “white space” characters such as line feeds, so reformatting it this way doesn’t affect its
meaning.
Page 33 of 147
WITSML Application Programming Interface
For those more comfortable with SQL syntax, this is equivalent to the “column” selection
criteria of the SQL Select statement:
SELECT column1, column2, … , columnN
Page 34 of 147
WITSML Application Programming Interface
Or in SQL syntax, this is equivalent to a “where" clause of the SQL Select statement:
SELECT column1, column2, … , columnN WHERE column1 = value1, …
Page 35 of 147
WITSML Application Programming Interface
LIMITATION
Query Templates are intended to provide a simple means of retrieving data objects based on
an equal comparison against a single value for each data item, either attribute or element.
They do not provide the ability to perform comparisons other than “equal”, or to allow for more
than one comparison against a given data item. While the default comparison is “equal”, a few
“date and time” elements will be documented to have “greater than” comparisons.
Page 36 of 147
WITSML Application Programming Interface
Page 37 of 147
WITSML Application Programming Interface
The selection criteria containing multiple recurring items should be kept simple and unambiguous.
For example, the following template requests mnemonic BPOS both explicitly (using
<mnemonic>BPOS<mnemonic>) and implicitly (using <mnemonic/>). Some servers may return
BPOS two times and some servers may only return it once while other servers may return an
error.
<realtimes xmlns="http://www.witsml.org/schemas/140ex">
<realtime uidWell="w1" uidWellbore="w1b">
<channel>
<mnemonic>BPOS<mnemonic>
</channel>
<channel>
<mnemonic/>
</channel>
</realtime>
</realtimes>
The results of the following query with nested recurring selection is also server dependent.
<mudLogs xmlns="http://www.witsml.org/schemas/140ex">
<mudLog uidWell="w1" uidWellbore="w1b" uid=”ml3>
<geologyInterval>
<typeLithology>interpreted<typeLithology>
<lithology>
<type>Limestone<type>
</lithology>
</geologyInterval>
<geologyInterval>
<typeLithology>cuttings typeLithology>
<lithology>
<type>Salt< type>
</lithology>
</geologyInterval>
</mudLog>
</mudLogs>
Page 38 of 147
WITSML Application Programming Interface
CONCEPT REINFORCEMENT
Page 39 of 147
WITSML Application Programming Interface
RESTRICTION
While the Capabilities objects are a type of “WITSML API object” they cannot be accessed by the
STORE interface’s standard data query functions. The Capabilities objects are not persisted as
data. They can only be accessed using the WMLx_GetCap functions and the CapabilitiesIn/Out
parameters of the various STORE interface functions.
Page 40 of 147
WITSML Application Programming Interface
Page 41 of 147
WITSML Application Programming Interface
Page 42 of 147
WITSML Application Programming Interface
Capability: the STORE functions, versions and data objects that the Server
supports for each function
Applies to: capServer object only
Conveyed as: function child element of the capServer element
dataObject child element of the function element
Syntax: <function name=”xxx”>
<dataObject>xxx</dataObject>
</function>
Default: none (Client should not assume capability exists if not explicitly listed)
Example: <capServer apiVers=”1.4.0”>
<function name=”WMLS_GetFromStore”>
<dataObject>well</dataObject>
<dataObject>wellbore</dataObject>
<dataObject>log</dataObject>
</function>
<function name=”WMLS_AddToStore”>
<dataObject>log</dataObject>
</function>
<function name=”WMLS_GetVersion”>
</function>
</capServer>
Notes: the example shows supports for only the three specified data object types
for WMLS_GetFromStore and only the log object for WMLS_AddToStore. The
function calls are from version 1.4.0 of the API. It also supports the
WMLS_GetVersion function. The capServer object does not need to specify the
WMLS_GetCap function, as this is implied if the capServer object is returned to
the Client.
Page 43 of 147
WITSML Application Programming Interface
Page 44 of 147
WITSML Application Programming Interface
4.5.1 WMLS_AddToStore
Adds one WITSML object to the server. The object is passed in a single XML document,
containing a root plural object element (e.g., <wells>) enclosing one singular object element (e.g.,
<well>). The object is added using the object type specified by WMLtypeIn plus the unique
identifier(s) present in the WITSML objects. An object with the same type and unique identifier(s)
must not already exist in the persistent store (use WMLS_UpdateInStore if updating an existing
object). If a uid value is not defined for the object in the XMLin file, the server will create one and
return the created uid value in SuppMsgOut (if there are no errors). All other parentage and lower
level (child) uid values must be defined in the XMLin file. See the notes for exceptions on the
realtime object.
integer = WMLS_AddToStore(
[in] string WMLtypeIn,
[in] string XMLin,
[in] string OptionsIn,
[in] string CapabilitiesIn,
[out] string SuppMsgOut
);
Parameters (all required):
WMLtypeIn - input string - not case sensitive
- one WITSML object type (see the specific WITSML data schema)
XMLin - input string - case sensitive (an XML document - see Notes)
- the WITSML object(s) to be added (see Notes)
- the XML should conform to the derived “write” schema where child and
parentage uids are mandatory.
OptionsIn - input string
- The keyword of ‘compressionMethod’ specifies a type of compression
that the client has applied to the contents of XMLin. Currently, the only
recognized values are "none" and “gzip”. A value of "none" specifies that
no compression has been applied to XMLin. The default is "none".
CapabilitiesIn - input string - case sensitive (an XML document)
- the client’s capabilities object (capClient) to be sent to the Server; may
be a null string if no capabilities object is to be provided to the Server
SuppMsgOut - output string
- Supplemental message text. If a uid is created for the object, the
created uid value will be returned in this string. The uid value will not be
returned if there are any errors.
Return Value:
short (see “Appendix C – Defined Values”)
Page 45 of 147
WITSML Application Programming Interface
Notes:
1) the object is added to the server using the passed type (WMLtypeIn) plus the unique
identifier(s) present in the object (XMLin); unique identifiers are not passed as separate
parameters. The following XMLin will add a new well object with the UID of “new1”:
wells xmlns=“http://www.witsml.org/schemas/140ex”>
<well uid=”new1”>
…
</well>
</wells>
2) the XML document must contain the plural container object as its root XML element,
even though it encloses only one WITSML object:
<wells …> [required even though there is only one <well> element]
<well uid=”new4”>
…
</well>
</wells>
3) upper/lowercase string data values present in the XMLin string will be stored exactly
as supplied: “preserving their case”. Subsequent WMLS_GetFromStore invocations will
return the string data values in their originally supplied case.
4) The realtime object is a special case that does not contain uid attributes (other than
well and wellbore parentage uids). When accessed via the Store Interface:
a) The unique identifier(s) of the realtime object will be natural keys (possibly
compound) for each node as documented in the schema.
b) For each wellbore, the store interface will only retain one realtime containing the
most recent definition of the header and containing the most recent data value of
each group (e.g., latest record or latest channel value for each mnemonic).
c) Because only the most recent data items will be retained, the unique identifiers
for the recurring data structures will not contain the data indices such that the
retained data will be unique based on the unique identifiers.
d) For WMLS_AddToStore an object uid can never be provided and a uid value will
never be returned.
e) WMLS_AddToStore will ”add” data sub-objects. But because only one data value
for each group column will be retained, the effect will be a “replace”.
For example, the following will add a specific channel value but the server will
also delete the existing value for the mnemonic in the specified group so the
result will be for this channel structure to replace the existing channel structure
with the same unique identity.
<realtimes xmlns=“http://www.witsml.org/schemas/140ex”>
<realtime uidWell="W-12" uidWellbore="B-01" />
<channel>
<id>Pits</id>
<mnemonic>RHO</mnemonic>
<dTim>2001-11-01T08:15:00.000Z</dTim>
<value>129.6</value>
</channel>
<commonData>
<serviceCategory>MWD Service</serviceCategory>
</commonData>
</realtime>
</realtimes>
Page 46 of 147
WITSML Application Programming Interface
4.5.2 WMLS_DeleteFromStore
Permanently deletes one WITSML object from the server. The object to be deleted is specified by
the WMLtypeIn and QueryIn parameters.
integer = WMLS_DeleteFromStore(
[in] string WMLtypeIn,
[in] string QueryIn,
[in] string OptionsIn,
[in] string CapabilitiesIn,
[out] string SuppMsgOut
);
Parameters (all required):
WMLtypeIn - input string - not case sensitive
- one WITSML object type (see the specific WITSML data schema)
QueryIn - input string - case sensitive (an XML document)
- a Query Template that specifies the unique identifiers of the objects to
be deleted
- Because QueryIn can contain empty elements, it cannot be schema
validated but otherwise the XML should conform to a derived “read”
schema where all elements and attributes are optional except for all
object and parentage uids which are mandatory.
OptionsIn - input string
- The keyword of ‘cascadedDelete’ specifies whether or not cascaded
deletes are to be enforced. A value of “true” specifies that the deletion of
an independent object will result in the deletion of all objects whose
identity depends on that object. For example, deleting a well object would
result in the deletion of all dependent wellbore objects as well as any
objects which depend on those wellbore objects. Deletion means that the
dependent object cannot be "found" via the WITSML API interface
regardless of whether some vestiges of it exist in a back-end database.
Referential integrity will be partly enforced by nullifying all uidRef values
that point to the deleted objects. A value of “false” specifies that an
independent object cannot be deleted until all dependent objects have
been deleted. The default value is “false”. Note that this option does not
apply to child..
CapabilitiesIn - input string - case sensitive (an XML document)
- the client’s capabilities object (capClient) to be sent to the Server; may
be a null string if no capabilities object is to be provided to the Server
SuppMsgOut - output string
- supplemental message text
Return Value:
short (see “Appendix C - Defined Values”)
Page 47 of 147
WITSML Application Programming Interface
Notes:
1) The client application specifies the object to be deleted using a Query Template,
passed via the QueryIn parameter. The uid for the object and its parents must be
specified. For example, the following will delete a specific wellbore object as identified by
the uidWell and uid attributes
<wellbores xmlns=“http://www.witsml.org/schemas/140ex”>
<wellbore uidWell=”12345” uid=”01” />
</wellbores>
2) If cascading deletes are not invoked, only bottom level objects should be deleted and
all child objects should be deleted before the parent is deleted. For example, a child
wellbore should be deleted before the parent well is deleted.
For example, to delete all the planned well objects from a server:
a) use WMLS_GetFromStore to query for the UID of all the planned well objects. The
QueryIn parameter of WMLS_GetFromStore would contain:
<wells xmlns=“http://www.witsml.org/schemas/140ex”>
<well uid=““>
<itemState>Planned</itemState>
</well>
</wells>
b) pass the returned well object(s) in multiple calls to WMLS_DeleteFromStore. The
QueryIn parameter of the first WMLS_DeleteFromStore might contain:
<wells xmlns=“http://www.witsml.org/schemas/140ex”>
<well uid=“123”/>
</wells>
While the next one might contain:
<wells xmlns=“http://www.witsml.org/schemas/140ex”>
<well uid=“456”/>
</wells>
4
but this can be accomplished in two steps – see the next note.
Page 48 of 147
WITSML Application Programming Interface
a) An empty attribute will delete the attribute. The following are exceptions to this
rule:
1. An empty uid attribute cannot be specified.
2. An empty uidRef attribute can only be specified if the related item has been
deleted.
3. An empty uom attribute cannot be specified.
b) An empty non-container element will delete its value and any attributes. For
example, the following will delete the country element in the specified well object.
<wells xmlns=“http://www.witsml.org/schemas/140ex”>
<well uid=”12345”>
<country />
</well>
</wells>
c) An empty recurring container with a unique identifier value will delete that specific
occurrence. For example, the following will delete a single trajectoryStation in the
specified object.
<trajectorys xmlns=“http://www.witsml.org/schemas/140ex”>
<trajectory uidWell="W-12" uidWellbore="B-01"
uid="pe84e">
<trajectoryStation uid=”123” />
</trajectory>
</trajectorys>
d) An empty recurring element (container or non-container) with no unique identifier
value will delete all occurrences. For example, the following will delete all
trajectoryStations in the specified object.
<trajectorys xmlns=“http://www.witsml.org/schemas/140ex”>
<trajectory uidWell="W-12" uidWellbore="B-01"
uid="pe84e">
<trajectoryStation/>
</trajectory>
</trajectorys>
e) An empty node cannot be specified for a mandatory element or attribute.
f) Deletion of sub-nodes, as opposed to the whole object, should only require user
update rights as opposed to user deletion rights.
Page 49 of 147
WITSML Application Programming Interface
6) Items can be deleted from realtime based on specified unique identifiers in the QueryIn
template. (See note in WMLS_AddToStore on the special nature of realtime when
accessed via STORE functions.)
a) Specifying only the realtime identifiers will delete the whole realtime for that wellbore.
For example, the following will delete the realtime object for a specific wellbore.
<realtimes xmlns=“http://www.witsml.org/schemas/140ex”>
<realtime uidWell="W-12" uidWellbore="B-01" />
</realtimes>
b) Specifying an empty header element will delete the whole header (and thus all data).
This is required in order to delete individual non-recurring child elements. For
example:
<realtimes xmlns=“http://www.witsml.org/schemas/140ex”>
<realtime uidWell="W-12" uidWellbore="B-01" />
<realtimeHeader/>
</realtime>
</realtimes>
c) Specifying a header group without any column identifiers will delete all data for the
whole group. That is both the group description and the data will be deleted. For
example, the following will delete a specific realtime group in the specified wellbore
<realtimes xmlns=“http://www.witsml.org/schemas/140ex”>
<realtime uidWell="W-12" uidWellbore="B-01" />
<realtimeHeader>
<groupDefinition>
<id>Pits</id>
</groupDefinition>
</realtimeHeader>
</realtime>
</realtimes>
d) Similar to a systematically growing object , if a group column identifier is specified
then all information associated with that column will be deleted. For example, the
following will delete the RHO column from the Pits group (including any channel or
record data).
<realtimes xmlns=“http://www.witsml.org/schemas/140ex”>
<realtime uidWell="W-12" uidWellbore="B-01" />
<realtimeHeader>
<groupDefinition>
<id>Pits</id>
<channelDefinition>
<mnemonic>Z</mnemonic>
</channelDefinition>
</groupDefinition>
</realtimeHeader>
</realtime>
</realtimes>
Page 50 of 147
WITSML Application Programming Interface
e) Specifying a specific data item (channel or record) will delete just that data item. For
example, the following will delete a specific channel value.
<realtimes xmlns=“http://www.witsml.org/schemas/140ex”>
<realtime uidWell="W-12" uidWellbore="B-01" />
<channel>
<id>Pits</id>
<mnemonic>RHO</mnemonic>
</channel>
</realtime>
</realtimes>
7) See section “STORE and PUBLISH behavior” for additional behavior related to
growing objects.
4.5.3 WMLS_GetBaseMsg
Returns a string containing the fixed ("base") message text associated with a return value.
string = WMLS_GetBaseMsg(
[in] integer ReturnValueIn
);
Parameters (all required):
ReturnValueIn - input integer
- a valid Return Value (see “Appendix C - Defined Values”)
Return Value:
string the fixed descriptive message text associated with the Return Value
(a null string is returned if ReturnValueIn is invalid)
Notes:
1) This function returns only the fixed description of the specified Return Value.
2) Variable, context-specific "supplemental" message text and diagnostic information, if
any, is returned in the SuppMsgOut parameter of the various STORE functions.
Page 51 of 147
WITSML Application Programming Interface
4.5.4 WMLS_GetCap
Returns the capServer object that describes the capabilities of the Server for one data schema.
The capServer object is returned in the form of an XML document. Multiple calls to
WMLS_GetCap are required in order to determine the capabilities of the server for all data
schemas that it supports.
integer = WMLS_GetCap(
[in] string OptionsIn,
[out] string CapabilitiesOut,
out] string SuppMsgOut
);
Parameters (all required):
OptionsIn - input string
- The keyword "dataVersion" with a value of a data schema version
specifies that capabilities information is desired for that particular data
version. The returned capabilities object will utilize the namespace that is
appropriate for the data version. For example:
dataVersion=1.4.0.0
requests information about data version 1.4.0.0 utilizing a 1.4.0
capabilities object. The data schemas that are supported by the server
can be determined using WMLS_GetVerson. The version string must
match the value of attribute "version" on the plural object container. The
default is for the server to return information about the oldest data
version that is supported by the server.
CapabilitiesOut - output string - case sensitive (an XML document)
SuppMsgOut - output string
- supplemental message text
Return Value:
short (see “Appendix C - Defined Values”)
Notes:
The OptionsIn parameter string is encoded utilizing the encoding rules for HTML form
content type application/x-www-form-urlencoded as specified at
http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.3.3
Note that this does not affect a single keyword and value pair.
Page 52 of 147
WITSML Application Programming Interface
4.5.5 WMLS_GetFromStore
Returns one or more WITSML objects from the Server. The objects are returned in the form of an
XML document containing a root plural object element (e.g., <wells>) enclosing one or more
singular object elements (e.g., <well>). The objects to be retrieved are identified by the object
type and Query Template passed to the function.
integer = WMLS_GetFromStore(
[in] string WMLtypeIn,
[in] string QueryIn,
[in] string OptionsIn,
[in] string CapabilitiesIn,
[out] string XMLout,
[out] string SuppMsgOut
);
Parameters (all required):
WMLtypeIn - input string - not case sensitive
- one WITSML object type
(see the specific WITSML data schema)
QueryIn - input string - case sensitive (an XML document)
- a Query Template that specifies the objects to be returned
- Because QueryIn can contain empty elements, it cannot be schema
validated but otherwise the XML should conform to a derived “read”
schema where all elements and attributes are optional.
OptionsIn - input string
- The keyword of ‘returnElements’ with a value of "all" requests that all
elements and attributes be returned. The template should be treated as if
all elements and attributes had explicitly been specified in the template. A
value of "requested" requests the mode of "you only get what you ask
for". For example:
returnElements=all
The default is "requested".
- The keyword of ‘compressionMethod’ specifies a type of compression
used for the parameters defined by compressionDirection. Currently, the
only recognized values are "none" and “gzip”. A value of "none" specifies
that no compression will be applied. The default is "none".
- The keyword of “compressionDirection” specifies which parameters will
be compressed with the specified method (possibly "none"). The
recognized values are "request", "response" or "both". A value of
"request" means that the client has applied the method to the contents of
QueryIn. A value of "response" means that the server must apply the
method to the contents of XMLout. A value of "both" means that both
QueryIn and XMLout will have the method applied. The default for
WMLS_GetFromStore is “response”.
Page 53 of 147
WITSML Application Programming Interface
Page 54 of 147
WITSML Application Programming Interface
7) If no value is available for an element or attribute then nothing will be returned. That is,
empty values will not be returned,
8) The elements will be returned in the order defined by the schema.
9) The order of the recurring data within an object is server dependent. The order that a
client added components will not necessarily be retained unless the schema documents
some significance of the order.
10) If multiple queries are contained in the template and one query fails then all of the
queries will fail.
11) The Extended Query Syntax that was in version 1.0 was eliminated from the standard
in version 1.2.
12) For various reasons, some servers may impose restrictions on retrievals. For
example, because the log data section can be so voluminous, a server may impose
constraints when retrieving curve data (as opposed to only retrieving header data):
a) A server may require that a specific log be identified
b) A server may not allow a request for all logs from one well.
c) A server may not allow a request for all logs from all wells.
d) In order to avoid clients killing a server the WITSML server might limit your result
set when you ask for log curves. The client should always compare the end index
in the log header with the end index in the result of its query. If there is a gap the
server has limited the result to a certain number of log points and the client will
need to ask again for the missing interval or at least for another interval
preceding the last result. A client should continue to do so until all the points in
the log curve have been retrieved.
13) The normal behavior for a server is to return only “what you ask for”. That is, in order
for an element to be returned it has to exist in the query template. This includes uom
attributes (see “Appendix B - Unit of Measure”).
a) For the special case of <customData> (see “Appendix G - Custom Data”), all
sub-nodes will be returned if only the customData element is specified. Querying
sub-nodes of customData is server dependent.
b) For the special category called growing objects, special behavior has been
defined. See “Appendix E – Special Handling of Growing Objects” for a
discussion of growing objects and their special behavior.
14) For realtime, if the client pulls more frequently than the server has fresh data then the
same realtime will be repetitively returned until new data is available. It is the clients
responsibility to inspect for duplicates based on the indices (e.g., dTim and md).
However, if the query specifies a value for dTimLastChange then it must be interpreted as
a request for only that data (channel or record) which has changed since (i.e., greater-
than) the specified value for dTimLastChange. This solution works for both depth and
time based data; however, best practice for all realtime data should have dTim defined by
the source system.
15) The OptionsIn parameter string is encoded utilizing the encoding rules for HTML form
content type application/x-www-form-urlencoded as specified at
http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.3.3
Note that this does not affect a single keyword and value pair.
Page 55 of 147
WITSML Application Programming Interface
16) The QueryIn template will not be schema compliant if it contains empty values. If it
does not contain empty values, it should be schema compliant against a derived “read”
schema where all elements and attributes are optional. The OptionsIn keyword
returnElements with a value of “all” can be used to construct a query without empty
values.
17) All of the criteria must be satisfied in a individual (singular) query or nothing (i.e., no
object) will be returned.
18) See note in WMLS_AddToStore on the special nature of realtime when accessed via
STORE functions.
4.5.6 WMLS_GetVersion
Returns a string containing the version(s) of data schemas that are supported by the server. A
particular data version can be passed to WMLS_GetCap via its OptionsIn parameter to request
information about the server capabilities with respect to that data version.
string = WMLS_GetVersion();
Parameters:
none
Return Value:
string - A comma separated list of schema versions (without spaces) that
are supported by the server. The oldest version should be listed
first, followed by the next oldest, etc.
Example: 1.2.0,1.4.0.0
Notes:
Each version number must match the contents of the version attribute on the plural
container element for each object.
For more information, see the topic on Versioning in the Terminology and Basic Concepts
section of this document.
Page 56 of 147
WITSML Application Programming Interface
4.5.7 WMLS_UpdateInStore
Updates one existing WITSML object on the Server. The WITSML object with the updated/added
values is passed in a single XML document, containing a root plural object element (e.g., <wells>)
enclosing one singular object element (e.g., <well>). The object to be updated is identified using
the object type specified by WMLtypeIn plus the unique identifier(s) present in the object. An
object with the same type and unique identifier(s) must already exist in the persistent store (use
WMLS_AddToStore if adding a new object).
integer = WMLS_UpdateInStore(
[in] string WMLtypeIn,
[in] string XMLin,
[in] string OptionsIn,
[in] string CapabilitiesIn,
[out] string SuppMsgOut);
Parameters (all required):
WMLtypeIn - input string - not case sensitive
- one WITSML object type (see the specific WITSML data schema)
XMLin - input string - case sensitive (an XML document)
- the updated WITSML object(s)
- the XML should conform to a derived “update” schema where all
elements and attributes are optional except for all uid attributes which are
mandatory.
OptionsIn - input string
- The keyword of ‘compressionMethod’ specifies a type of compression
that the client has applied to the contents of XMLin. Currently, the only
recognized values are "none" and “gzip”. A value of "none" specifies that
no compression has been applied to XMLin. The default is "none".
CapabilitiesIn - input string - case sensitive (an XML document)
- the client’s capabilities object (capClient) to be sent to the Server; may
be a null string if no capabilities object is to be provided to the Server
SuppMsgOut - output string
- supplemental message text
Return Value:
short (see “Appendix C - Defined Values”)
Page 57 of 147
WITSML Application Programming Interface
Notes:
For the purpose of the following discussion, a container is an element which contains
other elements. A non-container is an element which has a value instead of other
elements.
1) the document must contain the required plural container item as its root XML element
2) The XMLin document must uniquely identify one object to be updated by including the
unique identifier of the object.
3) An element (container or not) in an existing container occurrence (recurring or not) can
be altered without changing anything else in the container.
4) An attribute can be altered without changing anything else in the element.
5) Specifying a value for an existing non-container element will replace the value for that
element. There is no check to see if the value is actually different. For example, the
following will update the itemState of well “123”.
<wells xmlns=“http://www.witsml.org/schemas/140ex”>
<well uid=“123“>
<itemState>Planned</itemState>
</well>
</wells>
6) Specifying a value for an existing attribute will replace the value for that attribute.
There is no check to see if the value is actually different.
7) Any new element or attribute will be inserted. A recurring container with a new unique
identifier value is a new element. New elements or attributes cannot be empty. For
example, the following will insert a new trajectoryStation, assuming that it did not already
exist: If it already existed, it would change the value of name, etc
<trajectorys xmlns=“http://www.witsml.org/schemas/140ex”>
<trajectory uidWell="W-12" uidWellbore="B-01" uid="pe84e">
<trajectoryStation uid=”456”>
<name>new station</name>
</trajectoryStation>
</trajectory>
</trajectorys>
8) The result of the update must be schema compliant with the “write” schema. For
example, mandatory items cannot be totally eliminated because they are constrained by
minOccurs.
9) A uom attribute cannot be specified unless its corresponding value is specified. This
prevents any assumption that a client can influence the default unit of measure. For
example in the following, the md in the first station is not allowed but the md in the
second station is OK.
<trajectorys xmlns=“http://www.witsml.org/schemas/140ex”>
<trajectory uidWell="W-12" uidWellbore="B-01" uid="pe84e">
<trajectoryStation uid=”123”>
<md uom=”ft” />
</trajectoryStation> Invalid because the md value not specified.
<trajectoryStation uid=”123”>
<md uom=”ft”>667.4</md> OK because the md value is specified.
</trajectoryStation>
</trajectory>
</trajectorys>
Page 58 of 147
WITSML Application Programming Interface
10) See note in WMLS_AddToStore on the special nature of realtime when accessed via
STORE functions. When WMLS_UpdateInStore is used to update realtime, the natural
identifiers will be used in the documented behavior related to “unique identifiers”. For
example:
The following will modify the value of qualData in the definition of the specified channel
(assuming that groupDefinition/id and channelDefinition/mnemonic are unique identifiers).
<realtimes xmlns=“http://www.witsml.org/schemas/140ex”>
<realtime uidWell="W-12" uidWellbore="B-01" />
<realtimeHeader>
<groupDefinition>
<id>Pits</id>
<channelDefinition>
<mnemonic>RHO</mnemonic>
<qualData>good</qualData>
</channelDefinition>
</groupDefinition>
</realtimeHeader>
</realtime>
</realtimes>
Assuming that channel/id and channel/mnemonic are unique identifiers, the following will
either (a) add a specific channel structure if the channel does not yet exist or (b) update
the existing values of dTim and value if the channel for id and mnemonic already exists.
<realtimes xmlns=“http://www.witsml.org/schemas/140ex”>
<realtime uidWell="W-12" uidWellbore="B-01" />
<channel>
<id>Pits</id>
<mnemonic>RHO</mnemonic>
<dTim>2001-11-01T08:15:00.000Z</dTim>
<value>129.6</value>
</channel>
</realtime>
</realtimes>
Page 59 of 147
WITSML Application Programming Interface
11) You cannot include Object Selection criteria in the XML document passed in XMLin.
For example, you cannot change all the legal names of all the wells in Scotland by merely
specifying:
<wells xmlns=“http://www.witsml.org/schemas/140ex”>
<well>
<nameLegal>changed Legal Name</nameLegal>
<country>Scotland</country>
</well>
</wells>
WMLS_UpdateInStore would not be able to determine which values were selection
criteria and which were merely new values to be updated (and the update would fail
nevertheless, because there is no UID specified for well…see Note #2).
You can accomplish the same task in three steps, however:
a) use WMLS_GetFromStore to select the UIDs of all the wells in Scotland. The
QueryIn parameter passed to WMLS_GetFromStore would be:
<wells xmlns=“http://www.witsml.org/schemas/140ex”>
<well uid=””>
<nameLegal/>
<country>Scotland</country>
</well>
</wells>
This might return:
<wells xmlns=“http://www.witsml.org/schemas/140ex”>
<well uid=”123”>
<nameLegal>existing legal name of 123</nameLegal>
<country>Scotland</country>
</well>
<well uid=”456”>
<nameLegal>existing legal name of 456</nameLegal>
<country>Scotland</country>
</well>
</wells>
b) programmatically update the legal names in the returned document to their new
values and split into multiple documents:
<wells xmlns=“http://www.witsml.org/schemas/140ex”>
<well uid=”123”>
<nameLegal>changed legal name of 123</nameLegal>
</well>
</wells>
and
<wells xmlns=“http://www.witsml.org/schemas/140ex”>
<well uid=”456”>
<nameLegal>changed legal name of 456</nameLegal>
</well>
</wells>
c) pass the updated documents to WMLS_UpdateInStore in multiple calls. Each <well>
element will then update its persisted object with the new legal name
Page 60 of 147
WITSML Application Programming Interface
IMPORTANT
In order to ensure interoperability between implementations, the only part of the WSDL file that
should normally be modified is the location attribute of the SOAP address element.
Other than the location attribute, the WSDL file should be used exactly as shown in the
following file listing.
The WSDL file is also provided in the WITSML distribution media.
Page 61 of 147
WITSML Application Programming Interface
<message name='Store.WMLS_DeleteFromStore'>
<part name='WMLtypeIn' type='xsd:string'/>
<part name='QueryIn' type='xsd:string'/>
<part name='OptionsIn' type='xsd:string'/>
<part name='CapabilitiesIn' type='xsd:string'/>
</message>
<message name='Store.WMLS_DeleteFromStoreResponse'>
<part name='Result' type='xsd:short'/>
<part name='SuppMsgOut' type='xsd:string'/>
</message>
<message name='Store.WMLS_GetBaseMsg'>
<part name='ReturnValueIn' type='xsd:short'/>
</message>
<message name='Store.WMLS_GetBaseMsgResponse'>
<part name='Result' type='xsd:string'/>
</message>
Page 62 of 147
WITSML Application Programming Interface
<message name='Store.WMLS_GetCap'>
<part name='OptionsIn' type='xsd:string'/>
</message>
<message name='Store.WMLS_GetCapResponse'>
<part name='Result' type='xsd:short'/>
<part name='CapabilitiesOut' type='xsd:string'/>
<part name='SuppMsgOut' type='xsd:string'/>
</message>
<message name='Store.WMLS_GetFromStore'>
<part name='WMLtypeIn' type='xsd:string'/>
<part name='QueryIn' type='xsd:string'/>
<part name='OptionsIn' type='xsd:string'/>
<part name='CapabilitiesIn' type='xsd:string'/>
</message>
<message name='Store.WMLS_GetFromStoreResponse'>
<part name='Result' type='xsd:short'/>
<part name='XMLout' type='xsd:string'/>
<part name='SuppMsgOut' type='xsd:string'/>
</message>
<message name='Store.WMLS_GetVersion'>
</message>
<message name='Store.WMLS_GetVersionResponse'>
<part name='Result' type='xsd:string'/>
</message>
<message name='Store.WMLS_UpdateInStore'>
<part name='WMLtypeIn' type='xsd:string'/>
<part name='XMLin' type='xsd:string'/>
<part name='OptionsIn' type='xsd:string'/>
<part name='CapabilitiesIn' type='xsd:string'/>
</message>
<message name='Store.WMLS_UpdateInStoreResponse'>
<part name='Result' type='xsd:short'/>
<part name='SuppMsgOut' type='xsd:string'/>
</message>
<!-- <portType> element groups the functions (operations) into an interface -->
<portType name='StoreSoapPort'>
<!-- <operation> elements define the function signatures (operation name and parameters)
and associate the input and output messages -->
<!-- parameterOrder attribute values must be separated by a single space -->
<operation name='WMLS_AddToStore'
parameterOrder='WMLtypeIn XMLin OptionsIn CapabilitiesIn SuppMsgOut'>
<input message='wsdlns:Store.WMLS_AddToStore' />
<output message='wsdlns:Store.WMLS_AddToStoreResponse' />
</operation>
<operation name='WMLS_DeleteFromStore'
Page 63 of 147
WITSML Application Programming Interface
Page 64 of 147
WITSML Application Programming Interface
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />
</input>
<output>
<soap:body use='encoded' namespace='http://www.witsml.org/message/120'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />
</output>
</operation>
<operation name='WMLS_GetBaseMsg'>
<soap:operation
soapAction='http://www.witsml.org/action/120/Store.WMLS_GetBaseMsg' />
<input>
<soap:body use='encoded' namespace='http://www.witsml.org/message/120'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />
</input>
<output>
<soap:body use='encoded' namespace='http://www.witsml.org/message/120'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />
</output>
</operation>
<operation name='WMLS_GetCap'>
<soap:operation
soapAction='http://www.witsml.org/action/120/Store.WMLS_GetCap' />
<input>
<soap:body use='encoded' namespace='http://www.witsml.org/message/120'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />
</input>
<output>
<soap:body use='encoded' namespace='http://www.witsml.org/message/120'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />
</output>
</operation>
<operation name='WMLS_GetFromStore' >
<soap:operation
soapAction='http://www.witsml.org/action/120/Store.WMLS_GetFromStore' />
<input>
<soap:body use='encoded' namespace='http://www.witsml.org/message/120'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />
</input>
<output>
<soap:body use='encoded' namespace='http://www.witsml.org/message/120'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />
</output>
</operation>
<operation name='WMLS_GetVersion' >
<soap:operation soapAction='http://www.witsml.org/action/120/Store.WMLS_GetVersion' />
<input>
<soap:body use='encoded' namespace='http://www.witsml.org/message/120'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />
</input>
<output>
<soap:body use='encoded' namespace='http://www.witsml.org/message/120'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />
</output>
Page 65 of 147
WITSML Application Programming Interface
</operation>
Page 66 of 147
WITSML Application Programming Interface
4.6.2 Narrative
The only part of the WSDL file that should normally be modified is the location attribute of the
SOAP address element. This should be set to the URL of the Web Service (see
implementation specifics below):
<service name='WMLS' >
<port name='StoreSoapPort' binding='wsdlns:StoreSoapBinding' >
<soap:address location='http://yourorg.com/yourwebservice' />
</port>
</service>
The WSDL file complies with Version 1.1 of the Web Services Description Language
(www.w3.org/TR/wsdl)
The target namespace and wsdlns prefix used in the WSDL file are both declared as:
'http://www.witsml.org/wsdl/120'
<definitions name='WMLS'
targetNamespace='http://www.witsml.org/wsdl/120'
xmlns:wsdlns='http://www.witsml.org/wsdl/120'
A default namespace declaration is used to make the document more readable:
<definitions name='WMLS' targetNamespace='http://www.witsml.org/wsdl/120'
xmlns:wsdlns='http://www.witsml.org/wsdl/120'
xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns='http://schemas.xmlsoap.org/wsdl/'>
The soapAction attribute of the SOAP operation elements specify a WITSML-related URI:
http://www.witsml.org/action/120/Store.WMLS_xxxx
The soapAction attribute is used by the HTTP transport as the value of the SOAPAction
HTTP header. Its use is not clear as of this writing; SOAP 1.1 states that it can be used to
identify the “intent” of messages.
<operation name='WMLS_AddToStore' >
<soap:operation
soapAction='http://www.witsml.org/action/120/Store.WMLS_AddToStore' />
<input>
…
The namespace attribute of the SOAP body elements also specify a WITSML-related URI:
http://www.witsml.org/message/120
<operation name='WMLS_AddToStore' >
<soap:operation
soapAction='http://www.witsml.org/action/120/Store.WMLS_AddToStore' />
<input>
<soap:body use='encoded' namespace='http://www.witsml.org/message/120'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />
</input>
</operation>
…
Page 67 of 147
WITSML Application Programming Interface
Although XML generally ignores white-space, the values of certain XML attributes and
elements may be sensitive to the amount of white-space. For example, the parameterOrder
attribute of the <operation> element must have only a single space between parameters:
<operation name='WMLS_AddToStore'
parameterOrder='WMLtypeIn XMLin OptionsIn CapabilitiesIn SuppMsgOut'>
For an easy-to-read, understandable introduction to WSDL files, see the article titled “Web
Services Description Language (WSDL) Explained” by Carlos C. Tapang - Infotects (in the
Microsoft MSDN Library and elsewhere).
Page 68 of 147
WITSML Application Programming Interface
5. PUBLISH Interface
5.1 Introduction
The PUBLISH interface provides Subscriber applications the ability to:
query a Publisher for what data object types are available for publication
subscribe to changed WITSML data objects to be published at some time in the future
maintain its subscription requests held by a Publisher.
When using the PUBLISH interface, the actual transfer of the requested WITSML data objects
between Publisher and Subscriber is performed by the Publisher when changed data objects
matching the Subscription become available (see CONCEPT box on next page). Although the
Subscriber initiates the process by sending a Subscription request to the Publisher that specifies
the objects it wishes to have sent to it, it’s still a “push” model in the sense that the requested
data objects are eventually pushed from Publisher to Subscriber.
Both the WITSML Subscription request and published data objects are XML documents.
The functions exposed by the PUBLISH interface are prefixed with “WMLP_”.
The WMLP_ functions are exposed to client applications as SOAP methods (Remote Procedure
Call-style). A standardized Web Services Description Language (WSDL) file is used to define the
PUBLISH interface exposed via SOAP.
The PUBLISH interface defines only the SOAP-exposed functions needed by a Subscriber to
determine what is available for subscription, and for the Subscriber to manipulate its
subscriptions. It does not expose an interface for invoking the publication (push) operation.
Publication is performed internally by the PUBLISH implementation when data is available for
publication, based on the subscriptions the Publisher has accepted.
The PUBLISH implementation uses HTTP/S POST to publish (push) the requested data objects
to the Subscriber. SOAP is used only for the Subscriber to access the Publisher during the
subscription process, not for the publication of the data objects
CONCEPT
A subscription to a data object is a request to receive the data object - or portions thereof -
when a future “change” is made to the data object.
Adding, modifying or deleting an object constitutes a “change” to the object.
A Publisher does not send the matching data object(s) immediately upon receipt of a
subscription.
A Publisher will send the data object to the Subscriber only when/if the data object changes
after the receipt of the subscription.
If the Subscriber application needs a full set of objects as a starting-point, it should use the
STORE interface to retrieve the initial contents of the objects.
Page 69 of 147
WITSML Application Programming Interface
Here is an example of a subscriber requesting two subscriptions. The subscriber application uses
SOAP to invoke the WMLP_Subscribe function on the Publisher . It passes the two Subscription
Requests in the SubscriptionIn parameter:
RetVal = WMLP_Subscribe(SubscriptionIn,
OptionsIn,
SubscriptionOut,
SuppMsgOut)
The SubscriptionIn parameter might contain:
<subscriptions xmlns="http://www.witsml.org/api/140">
<subscription action=”add ”… >
<realtimes namespace="http://www.witsml.org/schemas/140ex">
<realtime … />
</realtimes>
<mudLogs namespace="http://www.witsml.org/schemas/140ex">
<mudLog … />
</mudLogs>
</subscription>
<subscription action=”add” … >
<wells namespace="http://www.witsml.org/schemas/140ex">
<well … />
</wells>
<wellbores namespace="http://www.witsml.org/schemas/140ex">
<wellbore … />
</wellbores>
<trajectorys namespace="http://www.witsml.org/schemas/140ex">
<trajectory … />
</trajectorys>
</subscription>
</subscriptions>
The Publisher inserts a return code (retCode attribute) into each Subscription Request (the
<subscription> element) and - if the subscription was accepted - the subscription identifier (idSub
attribute). It then returns the modified Subscription Requests to the Subscriber in the
SubscriptionOut parameter.
The Publisher also returns a value (RetVal) indicating the overall success or failure of the
function.
►Subscription Requests and their child elements - known as Subscription Templates - are
described in subsequent topics.
Page 70 of 147
WITSML Application Programming Interface
Page 71 of 147
WITSML Application Programming Interface
5
the Subscription object cannot specify the Subscription or Capabilities object types, however.
Those object types cannot be published.
Page 72 of 147
WITSML Application Programming Interface
CONCEPT
Subscription Requests are treated as separate, independent requests, even if received from and
targeted to the same Subscriber.
Consider the following two Subscription Requests from the same Subscriber:
<subscriptions ...>
<subscription>
<wells namespace="http://www.witsml.org/schemas/140ex">
<well uid="w1"/>
</wells>
</subscription>
<subscription>
<wells namespace="http://www.witsml.org/schemas/140ex">
<well/>
</wells>
</subscription>
</subscriptions>
When well object "w1" changes, the Publisher will send the well object once for the first
subscription, and a second time as a result of the second subscription.
► No attempt is made by the Publisher to merge, consolidate or rationalize "overlapping"
Subscription Requests.
The Subscription Request (<subscription>) element accepts the following XML attributes:
Page 73 of 147
WITSML Application Programming Interface
Page 74 of 147
WITSML Application Programming Interface
Page 75 of 147
WITSML Application Programming Interface
Page 76 of 147
WITSML Application Programming Interface
While verifying a subscription doesn’t modify its contents, a Publisher could track the date of last
verification, and use that information to determine which subscriptions are still being used and which
could be considered for “clean up”. Periodic subscription verification can help improve the reliability of
the Subscribe/Publish mechanism and prevent the buildup of “deadwood” subscriptions.
Page 77 of 147
WITSML Application Programming Interface
Page 78 of 147
WITSML Application Programming Interface
IMPLEMENTATION NOTE
The Publisher chooses what form the Subscription Identifier takes, such as a character or
numeric string. If a numeric value is used, it should be large enough to not “wrap” - and
cause duplicates IDs - within a reasonable amount of time.
5.2.4 test attribute - test network connectivity
Unless you request otherwise, whenever you request a new subscription or modify or verify an
existing one, a network test will first be performed by the Publisher to make sure it can contact
the Subscriber. The test will consist of an empty data object sent via HTTP/S POST from
Publisher to Subscriber, using the host, process, port, encrypt and idPub values specified in the
new/existing subscription.
► If the network test fails, no further processing will be done on the request and an error code
will be returned.
You may suppress the default network test by specifying the test attribute with a value of “false” in
your subscription object:
<subscriptions xmlns="http://www.witsml.org/api/140">
<subscription action=”add” test=”false” … >
…
</subscription>
</subscriptions>
If your Subscriber system is running and its HTTP/S listener process is active, you should allow the
network test to be performed by omitting the test=”false” attribute. Performing the test will help
prevent the situation in which you’ve requested a subscription, but then fail to receive any data,
because the subscription specified an invalid host or listening process.
Page 79 of 147
WITSML Application Programming Interface
5.2.5 host, process, port and encrypt attributes - specify the subscriber’s URL
In addition to an action and sometimes a subscription ID, each Subscription object must also
contain the following attribute:
host - the DNS host name or IP address of the system that will
receive the published data objects as HTTP/S POSTs.
Optionally, the Subscription object can specify:
encrypt - whether HTTP (encrypt=”false”) or HTTPS (encrypt=”true”) is
to be used to POST the data to the listening process. If omitted,
the default is “false” (use HTTP)
process - the name of the HTTP/S listener process on the “host” system,
including the directory/path name if needed. A leading delimiter
is not required.
port - the TCP port number on which the HTTP/S listener “process”
is listening. If omitted, the default is 80 (if encrypt="false" or
encrypt is omitted) or 443 (if encrypt="true")
The host, process, port and encrypt attributes are combined to create the URL of the system to
which the published data will be sent. A URL consists of:
protocol://host:port/process
The encrypt attribute determines whether http or https will be used as the protocol.
The host attribute specifies the host portion of the URL.
The port value - if explicitly supplied - is used to specify the port portion of the URL. If the port
attribute is supplied, it is separated from the host by a colon (":") character. If the port attribute is
not supplied, the colon character will not be present in the URL.
The process attribute specifies the process portion of the URL. If specified, a forward slash
character ("/") is used to delineate it.
Example:
<subscriptions xmlns="http://www.witsml.org/api/140">
<subscription host=”myhost.myorg.com”
process=”WMLR_Publish.aspx?id=Sense-898” … >
</subscription>
</subscriptions>
… will result in the URL: http://myhost.myorg.com/WMLR_Publish.aspx?id=Sense-898
In this example, the parameter after the question mark is being used to pass a client assigned
publisher identifier back to the client. When using this technique, the client name should be part
of the identifier.
Page 80 of 147
WITSML Application Programming Interface
IMPLEMENTATION NOTE
Page 81 of 147
WITSML Application Programming Interface
CONCEPT
The Publisher will check for changes to an object no more frequently than the updateInterval,
such that the latest state of the changed object is sent. For example, a channel may get
updated every second, but at the 5 second updateInterval, only the latest channel value will be
published.
The updateInterval does not specify a maximum period. If there have been no changes to the
data objects, no publication will occur (e.g., there is no maximum period).
The updateInterval specified in the subscription request also specifies the default interval for the
realtime object, unless over-ridden by the realtime object’s <interval> element.
Page 82 of 147
WITSML Application Programming Interface
Page 83 of 147
WITSML Application Programming Interface
The following describes the standard behavior of the Subscription Template. For data
objects that conform to special requirements, special handling has been defined that
extends this standard behavior (see Appendix D - Special Handling).
Now that we’ve described the Subscription Request element and its attributes, let’s now look at
Subscription Templates. A Subscription Template specifies the data object types and data items
within those objects that are to be published for a particular Subscription, much like the Query
Templates used by the STORE interface.
Here is our earlier example showing two Subscription Requests, each with their own Subscription
Templates:
<subscriptions xmlns="http://www.witsml.org/api/140">
<subscription … > ç Subscription Request #1
<wells … /> ß Subscription Template #1a
<wellbores … /> ß Subscription Template #1b
</subscription>
<subscription … > ç Subscription Request #2
<trajectorys … /> ß Subscription Template #2
</subscription>
</subscriptions>
Each Subscription Template specifies both:
the contents of the published data objects, by including those XML elements/attributes
that are to be sent by the Publisher, but without specifying a value for the
elements/attributes. The following example requests that a well object be published
whenever any well object on the Publisher is changed, and that the published well
objects are to contain only the country data item (and its parent items):
<subscriptions xmlns="http://www.witsml.org/api/140">
<subscription … >
<wells namespace="http://www.witsml.org/schemas/140ex">
<well><country/></well>
</wells>
</subscription>
</subscriptions>
The published well object might contain:
<wells>
<well>
<country>UK</country>
</well>
…
</wells>
Page 84 of 147
WITSML Application Programming Interface
The selection of which data objects are to be published, by including a value with the
XML elements and/or attributes. The following example requests that a well object be
published whenever a well object containing a country data item of “Norway” is changed:
<subscriptions xmlns="http://www.witsml.org/api/140">
<subscription … >
<wells namespace="http://www.witsml.org/schemas/140ex">
<well>
<country>Norway</country>
</well>
</wells>
</subscription>
</subscriptions>
The structural content of the published well object(s) would be the same as in the first
example above. The difference is that in the first example, a change to any well object will
result in a publication, while in the second example only a change to a well with a country
data item of “Norway” will result in a publication.
► The plural data object container provides for more than one Subscription Template for a given
WITSML data object type within one Subscription Request.
<subscriptions xmlns="http://www.witsml.org/api/140">
<subscription … >
<wells namespace="http://www.witsml.org/schemas/140ex">
<well uid="1"/>
<well uid="2"/>
</wells>
</subscription>
</subscriptions>
The plural container is required even if only one instance of a data object type is specified in the
Subscription Template.
Page 85 of 147
WITSML Application Programming Interface
IMPORTANT
The Subscription Template specifies only the data items that are to be published
when/if any data item in the data object is changed.
It does not specify the data items that are to be “monitored” for changes!
There is no relationship between the data item(s) which changed and those requested
to be returned by the Subscription Template. The data items that changed - and thus
triggered the object to be published - will be included in the published objects only if
they were specified in the Subscription Template.
IMPLEMENTATION NOTE
Page 86 of 147
WITSML Application Programming Interface
Page 87 of 147
WITSML Application Programming Interface
Based on this result a subscription can be submitted using the following template.
<realtimes xmlns="http://www.witsml.org/schemas/140ex">
<realtime uidWell="w1" uidWellbore="w1b">
<md uom=””/>
<realtimeHeader>
<channelDefinition>
<mnemonic>WOB</mnemonic>
</channelDefinition>
<channelDefinition>
<mnemonic>SPM</mnemonic>
</channelDefinition>
</realtimeHeader>
<channel>
<mnemonic/>
<value uom=/>
</channel>
</realtime>
</realtimes>
Page 88 of 147
WITSML Application Programming Interface
The realtimeHeader data will be returned with the first data that is published but not with
subsequent data. Thus the following sequence of messages might be published as a result of the
above subscription.
<realtimes xmlns="http://www.witsml.org/schemas/140ex">
<realtime uidWell="w1" uidWellbore="w1b" idSub=”12345”>
<md uom=”m”>3598.346</md>
<realtimeHeader>
<channelDefinition>
<mnemonic>WOB</mnemonic>
<channelDefinition>
<channelDefinition>
<mnemonic>SPM</mnemonic>
</channelDefinition>
</realtimeHeader>
<channel>
<mnemonic>SPM</mnemonic>
<value uom=”rpm”>78.160<value>
</channel>
<channel>
<mnemonic>WOB</mnemonic>
<value uom=”t”>5.979<value>
</channel>
</realtime>
</realtimes>
<realtimes xmlns="http://www.witsml.org/schemas/140ex">
<realtime uidWell="w1" uidWellbore="w1b" idSub=”12345”>
<md uom=”m”>3578.14</md>
<channel>
<mnemonic>SPM</mnemonic>
<value uom=”rpm”>78.160<value>
</channel>
<channel>
<mnemonic>WOB</mnemonic>
<value uom=”t”>5.979<value>
</channel>
</realtime>
</realtimes>
<realtimes xmlns="http://www.witsml.org/schemas/140ex">
<realtime uidWell="w1" uidWellbore="w1b" idSub=”12345”>
<md uom=”m”>3598.346</md>
<channel>
<mnemonic>SPM</mnemonic>
<value uom=”rpm”>78.172<value>
</channel>
</realtime>
</realtimes>
<realtimes xmlns="http://www.witsml.org/schemas/140ex">
<realtime uidWell="w1" uidWellbore="w1b" idSub=”12345”>
<md uom=”m”>3601.285</md>
<channel>
<mnemonic>WOB</mnemonic>
<value uom=”t”>5.967<value>
</channel>
</realtime>
</realtimes>
Page 89 of 147
WITSML Application Programming Interface
And so on. The md element defines the node index and the mnemonic element identifies the
column identifier for each data value.
When an object is deleted the Publisher should send only the unique identifiers (UID’s) of
the deleted object, regardless of the Subscription Template contents.
Because this manner of indicating a deleted object can be somewhat ambiguous, it is
strongly recommended that a subscriber perform a STORE interface query to the
originating system to verify that the object has in fact been deleted.
Page 90 of 147
WITSML Application Programming Interface
6
for a more rigorous definition of HTTP syntax, see http://www.w3.org/Protocols/rfc2616/rfc2616.html
Page 91 of 147
WITSML Application Programming Interface
5.5.2 Notes:
The Publisher places one or more WITSML data objects - in the form of a single XML
document - in the message body of the HTTP/S POST request.
Multiple WITSML data objects of the same type may be sent in one request.
The root element of the XML document must be a plural container element of the same
type as the data object(s), such as:
<wells…>
<well … />
<well … />
</wells>
The plural root element must be included even if there is only one data object.
The Authorization field may be omitted if no authorization is required by the subscriber.
Other HTTP Request fields may be included as needed.
5.5.3 Example:
POST /witsml/listener HTTP/1.1
Host: www.witsml.org
Content-Type: application/xml
Content-Length: 182
Authorization: BASIC QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Page 92 of 147
WITSML Application Programming Interface
RESTRICTION
While the Capabilities objects are a type of “WITSML object” they cannot be published. The
Capabilities objects are not persisted as data. They can only be accessed using the
WMLP_GetCap function and the CapabilitiesIn/Out parameters of the various PUBLISH interface
functions.
Page 93 of 147
WITSML Application Programming Interface
Page 94 of 147
WITSML Application Programming Interface
Page 95 of 147
WITSML Application Programming Interface
Page 96 of 147
WITSML Application Programming Interface
Page 97 of 147
WITSML Application Programming Interface
5.8.2 WMLP_GetCap
Returns the capPublisher object which represents the capabilities of the Publisher for one data
schema. The capPublisher object is returned in the form of an XML document. Multiple calls to
WMLP_GetCap are required in order to determine the capabilities of the server for all data
schemas that it supports.
integer = WMLP_GetCap(
[in] string OptionsIn,
[out] string CapabilitiesOut,
[out] string SuppMsgOut
);
Page 98 of 147
WITSML Application Programming Interface
5.8.3 WMLP_GetVersion
Returns a string containing the data version(s) that are supported by the Publisher. A particular
data version can be passed to WMLP_GetCap via its OptionsIn parameter to request information
about the server capabilities with respect to that data version.
string = WMLP_GetVersion();
Parameters:
none
Return Value:
string - A comma separated list of schema versions (without spaces) that
are supported by the server. The oldest version should be listed
first, followed by the next oldest, etc
Example: 1.2.0,1.4.0.0
Notes:
Each version number must match the contents of the version attribute on the plural
container element for each object.
For more information, see the topic on Versioning in the Terminology and Basic Concepts
section of this document.
Page 99 of 147
WITSML Application Programming Interface
5.8.4 WMLP_Subscribe
Receives and processes Subscription Requests from Subscribers.
integer = WMLP_Subscribe(
[in] string SubscriptionIn,
[in] string OptionsIn,
[in] string CapabilitiesIn,
[out] string SubscriptionOut,
[out] string SuppMsgOut
);
Parameters (all required):
SubscriptionIn – input string – case sensitive (an XML document)
- one or more WITSML Subscription Requests containing the object
types names to which a subscription is to be created, the subscriber’s
host and receiving process name and other properties of the
subscription.
OptionsIn - input string
- The keyword of ‘returnElements’ with a value of "all" requests that all
elements and attributes be returned. The template should be treated as if
all elements and attributes had explicitly been specified in the template. A
value of "requested" requests the mode of "you only get what you ask
for". The default is "requested". For example:
returnElements=all
CapabilitiesIn - input string - case sensitive (an XML document)
- the Subscriber’s capabilities object (capSubscriber) to be sent to the
Publisher; may be a null string if no capabilities object is to be provided
to the Publisher.
SubscriptionOut – output string – case sensitive (an XML document)
- the WITSML Subscription Requests returned by the Publisher with
return codes inserted for each subscription request.
SuppMsgOut - output string
- supplemental message text
Return Value:
short (see “Appendix C- Defined Values”)
Notes:
1) output parameters are valid only if Return Value = 1
2) For various reasons, some servers may impose restrictions on subscriptions. For
example:
a) A publisher may not allow more than one subscription (total).
b) A publisher may not allow more than one subscription per subscriber.
c) A publisher may not allow more than one subscription per object per subscriber.
d) When subscribing to realtime, a publisher may require that the subscriber specify a
specific well and/or wellbore and/or mnemonic.
e) A publisher may not allow multiple templates per subscription request.
IMPORTANT
<message name='Publish.WMLP_GetCap'>
<part name='OptionsIn' type='xsd:string'/>
</message>
<message name='Publish.WMLP_GetCapResponse'>
<part name='CapabilitiesOut' type='xsd:string'/>
<part name='SuppMsgOut' type='xsd:string'/>
<part name='Result' type='xsd:short'/>
</message>
<message name='Publish.WMLP_GetVersion'>
</message>
<message name='Publish.WMLP_GetVersionResponse'>
<part name='Result' type='xsd:string'/>
</message>
<message name='Publish.WMLP_Subscribe'>
<part name='SubscriptionIn' type='xsd:string'/>
<part name='OptionsIn' type='xsd:string'/>
<part name='CapabilitiesIn' type='xsd:string'/>
</message>
<message name='Publish.WMLP_SubscribeResponse'>
<part name='Result' type='xsd:short'/>
<part name='SubscriptionOut' type='xsd:string'/>
<part name='SuppMsgOut' type='xsd:string'/>
</message>
<!-- <portType> element groups the functions (operations) into an interface -->
<portType name='PublishSoapPort'>
<!-- <operation> elements define the function signatures (operation name and parameters)
and associate the input and output messages -->
<!-- parameterOrder attribute values must be separated by a single space -->
<operation name='WMLP_GetBaseMsg' parameterOrder='ReturnValueIn'>
<input message='wsdlns:Publish.WMLP_GetBaseMsg' />
<output message='wsdlns:Publish.WMLP_GetBaseMsgResponse' />
</operation>
<operation name='WMLP_GetCap'
parameterOrder='OptionsIn CapabilitiesOut SuppMsgOut'>
<input message='wsdlns:Publish.WMLP_GetCap' />
<output message='wsdlns:Publish.WMLP_GetCapResponse' />
</operation>
<operation name='WMLP_GetVersion'>
<input message='wsdlns:Publish.WMLP_GetVersion' />
<output message='wsdlns:Publish.WMLP_GetVersionResponse' />
</operation>
<operation name='WMLP_Subscribe'
parameterOrder='SubscriptionIn OptionsIn CapabilitiesIn SubscriptionOut SuppMsgOut'>
<input message='wsdlns:Publish.WMLP_Subscribe' />
<output message='wsdlns:Publish.WMLP_SubscribeResponse' />
</operation>
</portType>
<!-- Concrete Definitions Section - <binding> and <service> elements -->
<!-- <binding> specifies the protocol binding for each operation in the <portType> section
-->
<binding name='PublishSoapBinding' type='wsdlns:PublishSoapPort' >
<soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http' />
<operation name='WMLP_GetBaseMsg' >
<soap:operation
soapAction='http://www.witsml.org/action/120/Publish.WMLP_GetBaseMsg' />
<input>
<soap:body use='encoded' namespace='http://www.witsml.org/message/120'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />
</input>
<output>
<soap:body use='encoded' namespace='http://www.witsml.org/message/120'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />
</output>
</operation>
<operation name='WMLP_GetCap' >
<soap:operation soapAction='http://www.witsml.org/action/120/Publish.WMLP_GetCap' />
<input>
<soap:body use='encoded' namespace='http://www.witsml.org/message/120'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />
</input>
<output>
<soap:body use='encoded' namespace='http://www.witsml.org/message/120'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />
</output>
</operation>
<operation name='WMLP_GetVersion' >
<soap:operation
soapAction='http://www.witsml.org/action/120/Publish.WMLP_GetVersion' />
<input>
<soap:body use='encoded' namespace='http://www.witsml.org/message/120'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />
</input>
<output>
<soap:body use='encoded' namespace='http://www.witsml.org/message/120'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />
</output>
</operation>
<operation name='WMLP_Subscribe' >
<soap:operation
soapAction='http://www.witsml.org/action/120/Publish.WMLP_Subscribe' />
<input>
<soap:body use='encoded' namespace='http://www.witsml.org/message/120'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />
</input>
<output>
<soap:body use='encoded' namespace='http://www.witsml.org/message/120'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />
</output>
</operation>
</binding>
<!-- <service> specifies the portType for each binding and the URL of the service -->
<service name='WMLP' >
<port name='PublishSoapPort' binding='wsdlns:PublishSoapBinding' >
<soap:address location='http://yourorg.com/yourwebservice' />
</port>
</service>
</definitions>
5.9.2 Narrative
The only part of the WSDL file that should normally be modified is the location attribute of the
SOAP address element. This should be set to the URL of the Web Service (see
implementation specifics below):
<service name='WMLP' >
<port name='PublishSoapPort' binding='wsdlns:PublishSoapBinding' >
<soap:address location='http://yourorg.com/yourwebservice' />
</port>
</service>
The WSDL file complies with Version 1.1 of the Web Services Description Language
(www.w3.org/TR/wsdl)
The target namespace and wsdlns prefix used in the WSDL file are both declared as:
'http://www.witsml.org/wsdl/120
<definitions name='WMLP'
targetNamespace='http://www.witsml.org/wsdl/120'
xmlns:wsdlns='http://www.witsml.org/wsdl/120'
A default namespace declaration is used to make the document more readable:
<definitions name='WMLP' targetNamespace='http://www.witsml.org/wsdl/120'
xmlns:wsdlns='http://www.witsml.org/wsdl/120'
xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns='http://schemas.xmlsoap.org/wsdl/'>
The soapAction attribute of the SOAP operation elements specify a WITSML-related URI:
http://www.witsml.org/action/120/Publish.WMLP_xxxx
The soapAction attribute is used by the HTTP transport as the value of the SOAPAction
HTTP header. Its use is not clear as of this writing; SOAP 1.1 states that it can be used to
identify the “intent” of messages.
<operation name='WMLP_Subscribe' >
<soap:operation
soapAction='http://www.witsml.org/action/120/Publish.WMLP_Subscribe' />
<input>
…
The namespace attribute of the SOAP body elements also specify a WITSML-related URI:
http://www.witsml.org/message/120
<operation name='WMLP_Subscribe' >
<soap:operation
soapAction='http://www.witsml.org/action/120/Publish.WMLP_Subscribe' />
<input>
<soap:body use='encoded' namespace='http://www.witsml.org/message/120'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' />
</input>
</operation>
…
Although XML generally ignores white-space, the values of certain XML attributes and
elements may be sensitive to the amount of white-space. For example, the parameterOrder
attribute of the <operation> element must have only a single space between parameters:
<operation name='WMLP_Subscribe' parameterOrder='SubscriptionIn OptionsIn CapabilitiesIn
SubscriptionOut SuppMsgOut'>
For an easy-to-read, understandable introduction to WSDL files, see the article titled “Web
Services Description Language (WSDL) Explained” by Carlos C. Tapang - Infotects (in the
Microsoft MSDN Library and elsewhere).
<xsd:complexType>
<xsd:sequence>
<xsd:element name="mdTop" type="measure" minOccurs="0"/>
<xsd:element name="mdBottom" type="measure" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="uid" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="geologyInterval" minOccurs="0"
maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="typeLithology" type="xsd:string”/>
<xsd:element name="mdTop" type="measure>
<xsd:element name="mdBottom" type="measure" minOccurs="0"/>
<xsd:element name="lithology" minOccurs="0"
maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="type" type="xsd:string”/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="uid" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="commonData" type="cs_commonData" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="uidWell" type="xsd:string" use="required"/>
<xsd:attribute name="uidWellbore" type="xsd:string" use="required"/>
<xsd:attribute name="uid" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
<!-- -->
<xsd:element name="trajectorys">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="trajectory" maxOccurs="unbounded"> <!—trajectory object à
<xsd:complexType>
<xsd:sequence>
<xsd:element name="nameWell" type="xsd:string"/>
<xsd:element name="nameWellbore" type="xsd:string"/>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="objectGrowing" type="xsd:string" minOccurs="0"/>
<xsd:element name="mdMn" type="measure" minOccurs="0"/>
<xsd:element name="mdMx" type="measure" minOccurs="0"/>
<xsd:element name="trajectoryStation" minOccurs="0">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="md" type="measure" minOccurs="0"/>
<xsd:element name="mdDelta" type="measure" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="commonData" type="cs_commonData" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="uid" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="uidWell" type="xsd:string" use="required"/>
<xsd:attribute name="uidWellbore" type="xsd:string" use="required"/>
<xsd:attribute name="uid" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
<!-- -->
<xsd:element name="logs">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="log" maxOccurs="unbounded"> <!—log object à
<xsd:complexType>
<xsd:sequence>
<xsd:element name="nameWell" type="xsd:string"/>
<xsd:element name="nameWellbore" type="xsd:string"/>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="objectGrowing" type="xsd:string" minOccurs="0"/>
<xsd:element name="logHeader" minOccurs="0">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="dataRowCount" type="xsd:double"
minOccurs="0"/>
<xsd:element name="indexType" type="xsd:string"
minOccurs="0"/>
<xsd:element name="startIndex" type="xsd:double"
minOccurs="0"/>
<xsd:element name="endIndex" type="xsd:double"
minOccurs="0"/>
<xsd:element name="indexUnits" type="xsd:string"
minOccurs="0"/>
<xsd:element name="startDateTimeIndex" type="xsd:dateTime"
minOccurs="0"/>
<xsd:element name="endDateTimeIndex" type="xsd:dateTime"
minOccurs="0"/>
<xsd:element name="direction" type="xsd:string"
minOccurs="0"/>
<xsd:element name="indexCurve" type="xsd:string"
minOccurs="0"/>
<xsd:element name="logCurveInfo" minOccurs="0"
maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="mnemonic" type="xsd:string"
minOccurs="0"/>
<xsd:element name="nullValue" type="xsd:string"
minOccurs="0"/>
<xsd:element name="startIndex" type="xsd:double"
minOccurs="0"/>
<xsd:element name="endIndex" type="xsd:double"
minOccurs="0"/>
<xsd:element name="startDateTimeIndex"
type="xsd:dateTime" minOccurs="0"/>
<xsd:element name="endDateTimeIndex"
type="xsd:dateTime" minOccurs="0"/>
<xsd:element name="columnIndex" type="xsd:integer"
minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="logData" minOccurs="0">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="data" type="xsd:string" minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="commonData" type="cs_commonData" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="uidWell" type="xsd:string" use="required"/>
<xsd:attribute name="uidWellbore" type="xsd:string" use="required"/>
<xsd:attribute name="uid" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
<!-- -->
<xsd:element name="realtimes">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="realtime" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="dTim" type="xsd:dateTime" minOccurs="0"/>
<xsd:element name="md" type="measure"/>
<xsd:element name="realtimeHeader" minOccurs="0">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="nameWell" type="xsd:string"/>
<xsd:element name="nameWellbore" type="xsd:string"/>
<xsd:element name="channelDefinition" minOccurs="0">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="mnemonic" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="channel" minOccurs="0">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="mnemonic" type="xsd:string"
minOccurs="0"/>
<xsd:element name="md" type="measure" minOccurs="0"/>
<xsd:element name="dTim" type="xsd:dateTime"
minOccurs="0"/>
<xsd:element name="value" type="measure"/>
<xsd:element name="qualData" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="commonData" type="cs_commonData" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="uidWell" type="xsd:string" use="required"/>
<xsd:attribute name="uidWellbore" type="xsd:string" use="required"/>
<xsd:attribute name="idSub" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<!-- -->
<xsd:complexType name="measure">
<xsd:simpleContent>
<xsd:extension base="xsd:double">
<xsd:attribute name="uom" type="xsd:string" use="required"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<!-- -->
<xsd:complexType name="cs_commonData">
<xsd:sequence>
<xsd:element name="dTimCreation" type="xsd:dateTime" minOccurs="0"/>
<xsd:element name="dTimLastChange" type="xsd:dateTime" minOccurs="0"/>
<xsd:element name="serviceCategory" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<!-- -->
</xsd:schema>
7.2 Basics
The "uom" attribute is mandatory for all numeric values that need to be qualified with a unit of
measure indicator to provide the full context of an element value. The value of the uom attribute is
expected to match an ‘annotation’ attribute from the WITSML Units Dictionary XML file that is
included with the Data Schema.
For example, a WITSML document may contain the fragment:
<ropAv uom="ft/h">80.00</ropAv>
This specifies that the value for ropAv is measured in feet per hour ("ft/h").
The "uom" value of "ft/h" is the annotation for a UnitOfMeasure in the WITSML Units Dictionary
reference file as:
<UnitOfMeasure id="ftPh" annotation="ft/h">
<Name>feet/hour</Name>
<CatalogName>POSC</CatalogName>
<CatalogSymbol isExplicit="true">ft/h</CatalogSymbol>
<ConversionToBaseUnit baseUnit="m/s">
<Fraction>
<Numerator>0.3048</Numerator>
<Denominator>3600</Denominator>
</Fraction>
</ConversionToBaseUnit>
</UnitOfMeasure>
This gives a link to the base SI unit of meters per second and a suggested conversion to this
base unit.
In this way, any WITSML compliant document can be decoded by any application that can work
with SI units.
7.5 Responsibilities
If a unit is requested, a server / publisher will always populate the ‘uom’ attribute of an element
with an entry that describes the units of the element value. The ‘uom’ will align with the WITSML
units dictionary.
The source of the data should use consistent units within an object. For example, all length
measures in the same unit and all coordinates of the same type (e.g., measured depth) in the
same unit. The unit system should also be consistent (e.g., metric). The source might be a server
or it might be a client that adds data to a server.
A uom attribute is not part of the selection criteria. Specifying a particular uom value in a query
template is a request for the element value to be returned in those units But, the client /
subscriber should verify that the ‘uom’ in the returned document matches that requested and if
not, handle any mismatch as it sees fit.
If an empty uom attribute is specified in a query then a default unit will be returned.
The unit should not change in validated data but, since we are trying to support realtime
conditions, a server must be allowed to "fix" the data. If a unit element or uom attribute changes
then the client should retrieve the "modified" value because the unit is an integral part of the data
value. For a curve, the whole curve should be retrieved.
7.6 Updating
The WITSML Units Dictionary file) is included in the WITSML distribution media for each WITML
Data Schema version.
Updates to the Units Dictionary are made as part of the WITSML Data Schema revision process.
When objectGrowing is set to "growing", a client can monitor for appendages by polling for any
new growth since the previously known index. It is suggested that the client polling rate adapt to
the historical append rate for that object.
To accommodate the need to selectively retrieve or have published only a range of occurrences
of a structure, special handling rules have been defined for some types of data objects.
Generally, the data objects with special handling rules are those that:
1) have a relatively large number of occurrences of recurring data that is indexed in depth or
time
and
2) have additional occurrences of recurring data that are inserted (or updated) over time
(e.g., the object grows)
There are two types of these growing objects that are supported with special behavior: randomly
growing and systematically growing. For randomly growing object the indexes in the
substructures are unrelated and they may overlap or coexist in the index space. These
substructures must be assigned a uid attribute. For systematically growing objects, the equivalent
of a “table” is described and data is added one “row” at a time. It is assumed that the data does
not overlap in index space. These “row” structures are not assigned a uid attribute.
When this specification was issued, the following WITSML data objects were categorized
as growing objects
trajectory (random)
mudLog (random
log (systematic)
wellLog (systematic)
The special handling rules modify the standard behavior of Query and Subscription
templates, as well as the rules which determine what portions of these objects are eligible
for publication.
c. If a structural range value is specified and data nodes are not requested, the
range values are interpreted as meaning to include in the returned object only
information about those columns which have non-null data within that range. That
is, no (header) information will be returned about columns which do not have
non-null data in that range. The result will be the same as when data nodes are
requested except that data nodes will not be returned.
d. If a structural range element is specified and data nodes are not returned
(whether data nodes are requested or not), the range values that are returned
will reflect the values in the persistent store.
e. If no structural range value is specified, standard query rules apply and all nodes
– regardless of index – will be returned assuming that they match any other
specified selection criteria.
f. For a systematically growing object, if an informative range element is specified:
i. If a value is specified, then it will be ignored.
ii. If no data nodes are returned then the server will return a value that
reflects the persistent data in the server.
iii. If data nodes are returned then the server will return a value that reflects
the returned nodes.
g. For a systematically growing object, if a value for the row count is specified then
the server will limit the resultant number of data nodes to a maximum of that
value. The returned value for the row count will be the number of rows in the
persistent store.
h. For a systematically growing object, if no column identifier is specified then the
server will interpret it as a request for all columns.
2) In a WMLS_UpdateInStore template for a systematically growing object:
a. If a structural range value is not specified the server will interpret it as a request
to append the data nodes. For the purpose of this section, “append” means to
add new data whose index is greater than the current maximum index.
b. If a structural range value is specified, the server will interpret it as a request to
replace any data nodes within that range. This is logically an “insert” if no data
exists within the specified range. The structural range value must match the
index range in the new data. This allows the server to replace the same data
regardless of whether it uses the structural range or the range in the data.
c. If a new column identifier and data nodes with values are specified then the
values will be added to existing data nodes and new data nodes will be added if
required. The only other column identifier that can be specified is the index
column. A structural range must not be specified with this option but its absence
does not imply append.
d. If informative range values are specified, they will be ignored.
3) In a WMLS_DeleteFromStore template,
a. For a randomly growing object, specifying the uid of data node will delete that
node. This is consistent with normal behavior.
b. For a systematically growing object , if a structural range value is specified
i. The server will interpret it as a request to delete all data nodes with a
node index that is greater than or equal to the minimum range value and
less than or equal to the maximum range value.
ii. Specifying only the minimum range value will delete all data nodes with a
node index value that is greater than or equal to the range value.
iii. Specifying only the maximum range value will delete all data nodes with
a data index value that is less than or equal to the range value.
c. For a systematically growing object , if a column identifier is specified then all
information associated with that column will be deleted. A structural range can be
specified with this option in order to delete a subset of a column.
4) The structural range, overall range, informative range and row count elements are
considered to be read-only elements and any request to update them will be ignored by
the server without an error being issued.
For all other functions the normal STORE rules apply. For example, use WMLS_UpdateInStore to
add a data node in a randomly growing object by specifying a node with a new uid value.
The values for mdMn and mdMx are interpreted as meaning to include in the returned
trajectory object(s) all instances of the trajectoryStation structure where the measured
depth element (md) of the trajectoryStation structure is greater than or equal to mdMn and
less than or equal to mdMx.
If no value is specified for both the mdMn or mdMx elements, "standard" Query template handling
rules will apply, and all trajectory stations - regardless of depth - will be returned (assuming they
match any other specified selection criteria).
If a value is specified for mdMn and not for mdMx, all trajectoryStation occurrences with an md
value greater than or equal to mdMn will be returned. Likewise, if a value is specified for mdMx
and not for mdMn, all trajectoryStation occurrences with an md value less than or equal to mdMx
will be returned.
If there are no trajectoryStations with md values within the specified range of value(s) for
mdMn/mdMx, nothing will be returned because not all criteria will have been met
► As is true for Query templates in general, if the md element of the trajectoryStation structure is
to be returned, it must be explicitly specified in the Query:
<trajectory uidWell="W-12" uidWellbore="B-01" uid="pe84e">
<mdMn>3000</mdMn>
<mdMx>4000</mdMx>
…
<trajectoryStation … > query template requesting that the md
<md/> data item be returned in the
</trajectoryStation> trajectoryStation structure(s)
…
</trajectory>
The selection of which trajectoryStation(s) are to be returned is performed against the persisted
md value(s), whether the md item is specified in the Query template or not.
If a value is specified in the trajectory for mdMn or mdMx, and a value is also specified in the
trajectoryStation for md, the value of md in the trajectoryStation will be ignored:
<trajectory uidWell="W-12" uidWellbore="B-01" uid="pe84e">
<mdMn>3000</mdMn>
<mdMx>4000</mdMx>
…
<trajectoryStation …>
<md>5000</md> this value will be ignored
</trajectoryStation>
…
</trajectory>
The above query would return all trajectoryStation instances between 3000 and 4000 (inclusive).
The md element of the returned trajectoryStations will contain the persisted value for each.
Any values specified for an attribute or element of the trajectoryStation structure - other than the
md child element - are combined with the selection criteria specified by mdMn and mdMx. The
following example would return all trajectoryStations with mdDelta value of 10 within the 3000-
4000 depth range:
<trajectory uidWell="W-12" uidWellbore="B-01" uid="pe84e">
<mdMn>3000</mdMn>
<mdMx>4000</mdMx>
…
<trajectoryStation> criteria are combined
<mdDelta>10</mdDelta>
</trajectoryStation>
…
</trajectory>
The values for startMd and endMd are interpreted as meaning to include in the returned
mudLog object(s) all instances of the parameter and geologyInterval structures where the
measured depth top element (mdTop) of the parameter or geologyInterval is greater than or
equal to startMd of the mudLog and the measured depth bottom element (mdBottom) of the
parameter or geologyInterval is less than or equal to endMd of the mudLog.
If no value is specified for both the startMd or endMd elements, "standard" Query template
handling rules will apply, and all parameter or geologyIntervals - regardless of depth - will be
returned (assuming they match any other specified selection criteria).
If a value is specified for startMd and not for endMd, all parameter or geologyInterval occurrences
with an mdTop value greater than or equal to startMd will be returned. Likewise, if a value is
specified for endMd and not for startMd, all parameter or geologyInterval occurrences with an
mdBottom value less than or equal to endMd will be returned.
If there are no parameter or geologyIntervals with mdTop/Bottom values within the specified
range of value(s) for startMd/endMd, nothing will be returned because not all criteria will have
been met.
► As is true for Query templates in general, if the mdTop and/or mdBottom elements of the
parameter or geologyInterval structure are to be returned, they must be specified:
<mudLog uidWell="W-12" uidWellbore="B-01" uid="h45a">
<startMd>5010</startMd>
<endMd>5020</endMd>
…
<geologyInterval> query template requesting that the mdTop
<mdTop/> and mdBottom data items are to be
<mdBottom/> returned in the geologyInterval structure(s)
</geologyInterval>
</mudLog>
The selection of which parameter(s) or geologyInterval(s) are to be returned is performed against
the persisted mdTop/mdBottom value(s), whether the mdTop/mdBottom item is specified in the
Query template or not.
If a value is specified in the mudLog for startMd or endMd, and a value is also specified in the
parameter or geologyInterval for mdTop/mdBottom, the value of mdTop/mdBottom in the
geologyInterval will be ignored:
<mudLog uidWell="W-12" uidWellbore="B-01" uid="h45a">
<startMd>5010</startMd>
<endMd>5520</endMd>
…
< parameter >
<mdTop>4000</mdTop> this value will be ignored
</parameter >
</mudLog>
The above query will return all the parameters between 5010 and 5520 (inclusive). The mdTop
element of the returned parameters will contain the persisted value for each.
Any values specified for an attribute or element of the parameter or geologyInterval structure -
other than the mdTop/mdBottom element described above - are combined with the selection
criteria specified by startMd and endMd. The following query would return the geologyIntervals
between 5010 and 5510 which have a dolomite value of 1:
<mudLog uidWell="W-12" uidWellbore="B-01" uid="h45a">
<startMd>5010</startMd>
<endMd>5510</endMd>
… criteria are combined
<geologyInterval>
<dolomite>1</dolomite>
</geologyInterval>
</mudLog>
Here is an example of a simplified log object containing four log curves: Mdepth, ROP, Bit RPM
and ECD.
<log uidWell="W-12" uidWellbore="B-01" uid="L001">
<logHeader>
<dataRowCount>5</dataRowCount>
<indexType>measured depth</indexType> Metadata about
<startIndex>4050</startIndex> the entire log
<endIndex>4090</endIndex> (table)
<indexCurve>Mdepth</indexCurve>
<logCurveInfo>
<mnemonic>Mdepth</mnemonic>
<startIndex>4050</startIndex>
<endIndex>4090</endIndex>
<columnIndex>1</columnIndex>
</logCurveInfo>
<logCurveInfo>
<mnemonic>ROP</mnemonic>
<startIndex>4050</startIndex>
<endIndex>4090</endIndex>
<columnIndex>2</columnIndex>
</logCurveInfo> Metadata about
<logCurveInfo> individual curves
<mnemonic>Bit RPM</mnemonic> (column heading)
<nullValue>-99999</nullValue>
<startIndex>4050</startIndex>
<endIndex>4070</endIndex>
<columnIndex>3</columnIndex>
</logCurveInfo>
<logCurveInfo>
<mnemonic>ECD</mnemonic>
<startIndex>4060</startIndex>
<endIndex>4090</endIndex>
<columnIndex>4</columnIndex>
</logCurveInfo>
</logHeader>
<logData>
<data>4050, 37.11, 93.74, </data>
<data>4060, 9.85, 95, 1.33</data>
Intervals
<data>4070, 32.44, 89.19, 1.31</data>
(rows)
<data>4080, 29.03, -99999, 1.32</data>
<data>4090, 13.09, -99999, 1.34</data>
</logData>
</log>
Curves
(columns)
From dataRowCount we learn that the log has 5 data intervals. From the startIndex and endIndex
elements of the logHeader we can see that the entire log covers the range of 4050 thru 4090.
From the startIndex/endIndex elements of the four logCurveInfo elements, we see that the
Mdepth and ROP curves cover this same range. The Bit RPM curve, however, contains non-null
data only for 4050-4070 and the ECD curve contains non-null data only for 4060-4090.
The values for the four curves are stored in the log as four data points within each <data>
element - one data point for each curve. 7
…
<logData>
<data>4050, 37.11, 93.74, </data>
<data>4060, 9.85 95, 1.33</data>
<data>4070, 32.44, 89.19, 1.31</data> Intervals
<data>4080, 29.03, -99999, 1.32</data>
<data>4090, 13.09, -99999, 1.34</data>
</logData>
</log>
Curves
Our four curves happen to have ascending <columnIndex> values (Mdepth =1, ROP = 2, etc),
and so the first “column” in the <data> element contains the Mdepth values (4050, 4060, etc)
followed by the ROP values in column 2 (37.11, 9.85, etc), the Bit RPM values in column 3 and
the ECD values in column 4.
If a log curve has no value at a particular depth or time, the value for that column in that <data>
element will be the value of the nullValue element specified for that curve or - if no nullValue is
specified, a null string.
For example, the Bit RPM curve specifies a value of -99999 for its nullValue element. Therefore,
the Bit RPM (3rd) column of the <data> element uses a value of -99999 for the fourth and fifth
intervals to indicate null values. However, since the nullValue element was not specified for the
other log curves, a null string (consecutive commas) will be used to indicate null values for all
other curves. This is the case with the ECD (4th) column, in which a null string is used to indicate
a null value for the first interval.
Viewed another way, the five example <data> elements convey the following data points for our
four curves:
Interval
#1 #2 #3 #4 #5
Mdepth 4050 4060 4070 4080 4090
ROP 37.11 9.85 32.44 29.03 13.09
Bit RPM 93.74 95 89.19 -99999 -99999
ECD null-string 1.33 1.31 1.32 1.34
One of the curves in a log must be designated as the “Index Curve”. If the log is depth-based, the
Index Curve will be the curve containing the depth at which the values were taken. If it is a time-
based log, the Index Curve will be the curve containing the time of the measurement.
Our example is a depth-based log, and Mdepth (curve/column #1) is the Index Curve, in feet.
Therefore, the data points represent values taken every ten feet from 4050 through 4090 feet.
7
additional spaces have been inserted into the example <data> elements to make the example more easily readable.
Spaces would not be present between numeric values in actual <data> elements.
When a Query Template is received by the STORE interface for a log object, and if it contains
values for the startIndex and endIndex elements in the logHeader and the <logData> and
<data> elements are present, STORE will interpret this as meaning to return the data values
for all the specified log curves in the specified range(s). If a value for dataRowCount is
specified then the server will limit the resultant interval count to a maximum of that value.
To query the ROP and the Bit RPM curves in our example log object for data in the range of 4050
thru 4080 one would specify:
<log uidWell="W-12" uidWellbore="B-01" uid="L001">
<logHeader>
<startIndex>4050</startIndex>
<endIndex>4080</endIndex>8 query template requesting
<logCurveInfo> the ROP and Bit RPM
<mnemonic>ROP</mnemonic> curves from 4050 through
</logCurveInfo> 4080
<logCurveInfo>
<mnemonic>Bit RPM</mnemonic>
</logCurveInfo>
</logHeader>
<logData>
<data/>
</logData>
</log>
If a query specifies values for the start/endIndex elements in the logCurveInfo element, those
values will be ignored:
<logHeader>
<startIndex>4050</startIndex> query template specifying
<endIndex>4080</endIndex> extraneous start/endIndex values
<logCurveInfo>
under logCurveInfo
<mnemonic>ROP</mnemonic>
<startIndex>4060</startIndex> [ignored]
<endIndex>4070</endIndex> [ignored]
</logCurveInfo>
…
The above query will be interpreted as if it had specified:
<logHeader>
<startIndex>4050</startIndex>
<endIndex>4080</endIndex>
<logCurveInfo>
<mnemonic>ROP</mnemonic>
<startIndex></startIndex>
<endIndex></endIndex>
</logCurveInfo>
…
Therefore, the server will return its persisted start/endIndex values for the ROP curve.
8
Since the Bit RPM curve in the example contains data only up to interval 4070, this query will
result in null values being returned for the Bit RPM curve in the intervals above 4070.
Here is another example query requesting the data for our example ROP and Bit RPM curves for
the interval range 4060-4100 (inclusive):
<log>
<logHeader>
<dataRowCount>3</dataRowCount>
<startIndex>4060</startIndex>
<endIndex>4100</endIndex>
<logCurveInfo>
<mnemonic>Mdepth</mnemonic>
<startIndex></startIndex>
<endIndex></endIndex>
<columnIndex></columnIndex>
<nullValue></nullValue>
</logCurveInfo>
<logCurveInfo>
<mnemonic>Bit RPM</mnemonic>
<startIndex></startIndex>
<endIndex></endIndex>
<columnIndex></columnIndex>
<nullValue></nullValue>
</logCurveInfo>
</logCurveInfo>
<mnemonic>ECD</mnemonic>
<startIndex></startIndex>
<endIndex></endIndex>
<columnIndex></columnIndex>
<nullValue></nullValue>
</logCurveInfo>
</logHeader>
<logData>
<data>
</logData>
</log>
Let us now look at what would be returned by this query.
Recalling that our stored log object contains:
Mdepth Bit
RPM ECD
¯ ¯ ¯
<data>4050, 37.11, 93.74, </data>
<data>4060, 9.85, 95, 1.33</data>
<data>4070, 32.44, 89.19, 1.31</data>
<data>4080, 29.03, -99999, 1.32</data>
<data>4090, 13.09, -99999, 1.34</data>
And we specified the range 4060 through 4100 for these three curves:
Mdepth RPM (curve/column #1 in the stored data)
Bit RPM (curve/column #3 in the stored data)
ECD (curve/column #4 in the stored data)
Here is a discussion that explains why the query returned the results it did…
A - The start/endIndex values returned in the logHeader will encompass the range of values in
the returned curves (not necessarily the entire range of values in the persisted log, nor the range
of values that was requested in the query). In our example, we requested the range of 4060-
4100. However, none of the requested non-index curves contained data greater than interval
4090. Therefore, the values returned in the logHeader were adjusted to reflect the range actually
returned in the curves, in order to maintain the internal consistency of the returned log object.
Note also that the interval for index 4090 was not returned because a maximum of three intervals
was requested.
queried for: <logHeader>
<startIndex>4060</startIndex>
<endIndex>4100</endIndex>
returned: <logHeader>
<startIndex>4060</startIndex>
<endIndex>4080</endIndex> [adjusted]
B - While the Bit RPM curve data was persisted by the server as curve #3, and ECD data as
curve #4, these index values are only relative to the other curves stored with the log. They are
not absolute, unchanging values. For example, when the Bit RPM and ECD curves’ data values
are returned to the client, the curves will have been assigned new index numbers relative to the
other curves returned by that particular query. In our example, while the Bit RPM curve data was
originally stored as curve #3, it is returned as curve #2. Likewise, the ECD data was stored as
curve #4, but is returned as curve #3. The server adjusts the index values (<columnIndex>
element in the logCurveInfo headers) of the returned objects to reflect the column index within
the returned <data> elements. The client must use the returned columnIndex value in the
logCurveInfo from that particular query in order to properly interpret the returned <data>
elements.
The logCurveInfo section of the returned log object will also have been adjusted by the server to
reflect the actual position of the Index Curve in the returned <data> elements. Although shown as
columnIndex 1 in our examples, the Index Curve does not necessarily occupy columnIndex 1 in
the stored log or in the returned <data> elements.
We could request all curves by using an empty mnemonic. The following query would return the
entire contents of the log.
<log uidWell="W-12" uidWellbore="B-01" uid="L001">
<logHeader>
<dataRowCount></dataRowCount>
<indexType></indexType>
<startIndex></startIndex>
<endIndex></endIndex>
<indexCurve></indexCurve>
<logCurveInfo>
<mnemonic></mnemonic>
<startIndex></startIndex>
<endIndex></endIndex>
<columnIndex></columnIndex>
</logCurveInfo>
</logHeader>
<logData>
<data></data>
</logData>
</log>
Updating rows in a systematically growing object without specifying start index or end index
will result in the rows being appended to the existing rows in the object.
Updating rows in a systematically growing object while specifying start index or end index will
result in the specified rows being replaced. A start index will request replacement of any row
with an index value greater than or equal to start index. An end index will request
replacement of any row with an index value less than or equal to end index.
Specifying a start index or an end index in a systematically growing object will delete the
corresponding data.
Updating a systematically growing object with a new column will result in the column
values being added in the appropriate rows.
Specifying a column identifier in the header will result in the corresponding column being
deleted.
Here's a summary of the parts of growing objects that are eligible to be published, based on the
type of change:
Type of Change Eligible for Publication
new object all non-recurring data
and
all instances of recurring structure
update of non-recurring data all non-recurring data
add of new recurring data all non-recurring data
and
new instance(s) of recurring structure
update of existing recurring data all non-recurring data
and
updated instance(s) of recurring structure
Once the Publisher has determined which part of these objects are eligible for publication, it then
applies the Subscription Template to determine whether the Subscriber has requested this
particular object (and which portions of the object).
Parts
Changed Eligible for Parts to be
Object Publication Published
STEP 1 STEP 2
12.1 Namespace
Custom data definitions should use a namespace URI different from the one used by WITSML
(http://www.witsml.org/schemas/nnn).
Here is a WITSML well object that uses the xmlns attribute to declare a custom namespace prefix of "cns"
associated with the URI http://www.my.org/schemas/100.
The object includes two custom data elements (cd1 and cd2) defined in that custom data namespace.
<?xml version="1.0" encoding="UTF-8"?>
<wells xmlns="http://www.witsml.org/schemas/140ex"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cns="http://www.my.org/schemas/100"> ç custom ns declaration
<well uid="W-1">
… WITSML-defined elements and attributes …
<customData>
<cns:cd1>value of cd1</cns:cd1>
<cns:cd2>value of cd2</cns:cd2>
</customData>
</well>
</wells>
Note that in this example the WITSML-defined elements and attributes do not require a namespace prefix,
since they use the default namespace declaration.