Work on SPV XML detail member.
authorBen Pfaff <blp@cs.stanford.edu>
Mon, 18 Jan 2016 06:14:51 +0000 (22:14 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Mon, 18 Jan 2016 06:14:51 +0000 (22:14 -0800)
detail-xml
spv-file-format.texi

index 742b5f9a7cda43cdb8a79cc45fd83ae3664292f1..1684915bf54c9f3034f6f68f75dd7fd352515940 100644 (file)
@@ -1,4 +1,4 @@
-visualization :=
+visualization := [creator date id? lang name style type version]
     extension?
     userSource
     (sourceVariable | derivedVariable)+
@@ -9,66 +9,123 @@ visualization :=
     layerController?
 
 extension :=
-
-userSource :=
-
- sourceVariable := extension* (format | stringFormat)?
-derivedVariable := extension* (format | stringFormat valueMapEntry*)?
-
-format := (affix+ | relabel)?
+    [(combinedFootnotes
+      | from helpId
+      | minWidthSet maxWidthSet
+      | showGridline)?
+     numRows?
+     id?]
+      
+userSource := [id missing?]
+
+sourceVariable :=
+    [id categorical source sourceName dependsOn? label? labelVariable?]
+    extension* (format | stringFormat)?
+derivedVariable :=
+    [id categorical value dependsOn?]
+    extension* (format | stringFormat valueMapEntry*)?
+valueMapEntry := [id? from to]
+
+format :=
+    [errorCharacter?
+     (minimumFractionDigits maximumFractionDigits)? /* maybe not for baseFormat=dateTime */
+     baseFormat?
+     (baseFormat=dateTime or baseFormat=elapsedTime:
+      dayPadding hourFormat hourPadding minutePadding showDay showSecond)
+     (baseFormat=dateTime only:
+      dayOfMonthPadding dayType monthFormat showMonth showYear yearAbbreviation separatorChars mdyOrder)
+     (baseFormat=elapsedTime only:
+      secondPadding showMillis useGrouping)]
+    (affix+ | relabel)?
 dateTimeFormat :=
-numberFormat := affix?
+    [baseFormat
+     (baseFormat=dateTime:
+      dayOfMonthPadding dayPadding dayType hourFormat hourPadding mdyOrder minutePadding monthFormat separatorChars showDay showHour showMinute showMonth showSecond showYear yearAbbreviation)
+     (baseFormat=time:
+      hourFormat hourPadding minutePadding secondPadding showHour showMillis showMinute showSecond)]
+numberFormat :=
+    [minimumIntegerDigits minimumFractionDigits maximumFractionDigits
+     (scientific small | suffix) useGrouping]
+    affix?
 stringFormat := (affix | relabel+)?
-affix :=
-relabel :=
-
-valueMapEntry :=
-
-graph := location+ coordinates faceting facetLayout interval
-
-location :=
-
-coordinates :=
-faceting := cross layer*
-interval := labeling footnotes?
-labeling := (format | formatting | footnotes)*
-formatting := formatMapping*
-formatMapping := format
-footnotes := footnoteMapping+
-footnoteMapping :=
-
-cross := nest+
-nest := variableReference+
-variableReference :=
-
-facetLayout := tableLayout facetLevel+ setCellProperties*
-tableLayout :=
-facetLevel := axis
-
-axis := label? majorTicks
-label := descriptionGroup | text+
-majorTicks := gridline?
-gridline :=
-
-descriptionGroup := description+ text
-description :=
-text := <text>
-paragraph :=
-
-setCellProperties := setMetadata setStyle* setFormat+ union?
-setMetadata :=
-setStyle :=
-setFormat := dateTimeFormat | format | numberFormat | stringFormat+
-
-labelFrame := location+ label paragraph?
-container := extension? location+ labelFrame+
+affix := [id? definesReference position suffix value]
+relabel := [from to]
+
+graph :=
+    [id cellStyle style]
+    location+ coordinates faceting facetLayout interval
+
+location := [id? method part (min | target | value)?]
+
+coordinates := [id]
+faceting := [id] cross layer*
+interval := [id style] labeling footnotes?
+labeling := [id? style? variable] (format | formatting | footnotes)*
+formatting := [id? variable] formatMapping*
+formatMapping := [id? from] format
+footnotes := [id? superscript variable] footnoteMapping+
+footnoteMapping := [id? from to definesReference]
+
+cross := [id?] nest+
+nest := [id?] variableReference+
+variableReference := [ref]
+
+facetLayout := [id?] tableLayout facetLevel+ setCellProperties*
+tableLayout := [(id style)? fitCells? verticalTitlesInCorner]
+facetLevel := [id gap level] axis
+
+axis := [id? style] label? majorTicks
+label :=
+    [id? style (purpose | textFrameStyle | purpose textFrameStyle)]
+    descriptionGroup | text+
+majorTicks := [id labelAngle length style tickFrameStyle] gridline?
+gridline := [id style zOrder]
+
+descriptionGroup := [id? separator target] description+ text
+description := [id? name]
+text := [id? (usesReference | definesReference position)?] <text>
+paragraph := [id? hangingIndent]
+
+setCellProperties :=
+    [id? applyToConverse]
+    setMetadata setStyle* setFormat+ union?
+setMetadata := [id? key target value]
+setStyle := [id? style target]
+setFormat :=
+    [id? target reset?]
+    dateTimeFormat | format | numberFormat | stringFormat+
+
+labelFrame := [id style] location+ label paragraph?
+container := [id style] extension? location+ labelFrame+
 
 style :=
-
-layer :=
-layerController :=
-
-union := intersect+
-intersect := intersectWhere | where+
-intersectWhere :=
-where :=
+    [id
+     (border-bottom border-bottom-color?)?
+     (border-left border-left-color?)?
+     (border-right border-right-color?)?
+     (border-top border-top-color?)
+     (color? color2)?
+     width?]
+style :=
+    [id
+     font-family?
+     font-size?
+     font-style?
+     font-weight?
+     labelAngle?
+     labelLocationHorizontal?
+     (labelLocationVertical
+      margin-bottom margin-left margin-right margin-top
+      textAlignment
+      size?)?
+     visible?
+     color? color2?
+     
+
+layer := [id? value variable method? visible?]
+layerController := [id? source target]
+
+union := [id] intersect+
+intersect := [id?] intersectWhere | where+
+intersectWhere := [id variable variable2]
+where := [id? include variable]
index ee99c24051c9eddff1b14ceb1220956e45e3131f..789a77707ce4d2894d80daec9f8af2975cd30ccb 100644 (file)
@@ -157,11 +157,11 @@ times.
 * SPV @code{text} Element (Inside @code{pageParagraph})::
 @end menu
 
-@node SPV heading Element
+@node SPV Structure heading Element
 @subsection The @code{heading} Element
 
 Parent: Document root or @code{heading} @*
-Contents: [@code{pageSetup}] @code{label} (@code{container} @math{|} @code{heading})*
+Contents: @code{pageSetup}? @code{label} (@code{container} @math{|} @code{heading})*
 
 The root of a structure member is a @code{heading}, which represents a
 section of output beginning with a title (the @code{label}) and
@@ -234,7 +234,7 @@ The output language, e.g.@: @code{en}, @code{it}, @code{es},
 @code{de}, @code{pt-BR}.
 @end defvr
 
-@node SPV label Element
+@node SPV Structure label Element
 @subsection The @code{label} Element
 
 Parent: @code{heading} or @code{container} @*
@@ -255,11 +255,11 @@ no text.
 
 This element has no attributes.
 
-@node SPV container Element
+@node SPV Structure container Element
 @subsection The @code{container} Element
 
 Parent: @code{heading} @*
-Contents: @code{label} [@code{table} @math{|} @code{text}]
+Contents: @code{label} (@code{table} @math{|} @code{text})?
 
 A @code{container} serves to label a @code{table} or a @code{text}
 item.
@@ -282,7 +282,7 @@ The width of the container in the form @code{@var{n}px}, e.g.@:
 @code{1097px}.
 @end defvr
 
-@node SPV text Element (Inside @code{container})
+@node SPV Structure text Element (Inside @code{container})
 @subsection The @code{text} Element (Inside @code{container})
 
 Parent: @code{container} @*
@@ -308,7 +308,7 @@ of where @code{commandName} is present but set to the empty string.
 As on the @code{heading} element.
 @end defvr
 
-@node SPV html Element
+@node SPV Structure html Element
 @subsection The @code{html} Element
 
 Parent: @code{text} @*
@@ -327,7 +327,7 @@ This element has the following attributes.
 This always contains @code{en} in the corpus.
 @end defvr
 
-@node SPV table Element
+@node SPV Structure table Element
 @subsection The @code{table} Element
 
 Parent: @code{container} @*
@@ -361,7 +361,7 @@ As on the @code{heading} element.  In the corpus, this is only present
 for version 21 and up and always includes all 8 digits.
 @end defvr
 
-@node SPV tableStructure Element
+@node SPV Structure tableStructure Element
 @subsection The @code{tableStructure} Element
 
 Parent: @code{table} @*
@@ -369,7 +369,7 @@ Contents: @code{dataPath}
 
 This element has no attributes.
 
-@node SPV dataPath Element
+@node SPV Structure dataPath Element
 @subsection The @code{dataPath} Element
 
 Parent: @code{tableStructure} @*
@@ -380,7 +380,7 @@ e.g.@: @code{0000000001437_lightTableData.bin}.
 
 This element has no attributes.
 
-@node SPV pageSetup Element
+@node SPV Structure pageSetup Element
 @subsection The @code{pageSetup} Element
 
 Parent: @code{heading} @*
@@ -419,7 +419,7 @@ Always @code{0deg}.
 Always @code{12pt}.
 @end defvr
 
-@node SPV pageHeader and pageFooter Elements
+@node SPV Structure pageHeader and pageFooter Elements
 @subsection The @code{pageHeader} and @code{pageFooter} Elements
 
 Parent: @code{pageSetup} @*
@@ -427,7 +427,7 @@ Contents: @code{pageParagraph}*
 
 This element has no attributes.
 
-@node SPV pageParagraph Element
+@node SPV Structure pageParagraph Element
 @subsection The @code{pageParagraph} Element
 
 Parent: @code{pageHeader} or @code{pageFooter} @*
@@ -437,11 +437,11 @@ Text to go at the top or bottom of a page, respectively.
 
 This element has no attributes.
 
-@node SPV @code{text} Element (Inside @code{pageParagraph})
+@node SPV Structure @code{text} Element (Inside @code{pageParagraph})
 @subsection The @code{text} Element (Inside @code{pageParagraph})
 
 Parent: @code{pageParagraph} @*
-Contents: [CDATA]
+Contents: CDATA?
 
 This @code{text} element is nested inside a @code{pageParagraph}.  There
 is a different @code{text} element that is nested inside a
@@ -1092,8 +1092,9 @@ The Style, if present, changes the style for this individual Value.
 Whereas the light binary format represents everything about a given
 pivot table, the legacy binary format conceptually consists of a
 number of named sources, each of which consists of a number of named
-series, each of which is a 1-dimensional array of numbers or strings
-or a mix.  Thus, the legacy binary member format is quite simple.
+variables, each of which is a 1-dimensional array of numbers or
+strings or a mix.  Thus, the legacy binary member format is quite
+simple.
 
 This section uses the same context-free grammar notation as in the
 previous section, with the following additions:
@@ -1140,18 +1141,19 @@ The following sections go into more detail.
 @cartouche
 @format
 Metadata @result{}
-    int[@t{per-series}] int[@t{n-series}] int[@t{offset}]
+    int[@t{n-data}] int[@t{n-variables}] int[@t{offset}]
     vAF(byte*32[@t{source-name}])
     vB0(byte*64[@t{source-name}] int[@t{x}])
 @end format
 @end cartouche
 
-A data source consists of @code{n-series} series of data, with
-@code{per-series} data values per series.
+A data source has @code{n-variables} variables, each with
+@code{n-data} data values.
 
 @code{source-name} is a 32- or 64-byte string padded on the right with
-zero bytes.  The names that appear in the corpus are very generic,
-usually @code{tableData} or @code{source0}.
+zero bytes.  The names that appear in the corpus are very generic:
+usually @code{tableData} for pivot table data or @code{source0} for
+chart data.
 
 A given Metadata's @code{offset} is the offset, in bytes, from the
 beginning of the member to the start of the corresponding Data.  This
@@ -1166,26 +1168,25 @@ The meaning of @code{x} in version 0xb0 is unknown.
 
 @cartouche
 @format
-Data @result{} NumericData StringData?
-NumericData @result{} NumericSeries*[@t{n-series}]
-NumericSeries @result{} byte*288[@t{series-name}] double*[@t{per-series}]
+Data @result{} NumericData*[@t{n-variables}] StringData?
+NumericData @result{} byte*288[@t{variable-name}] double*[@t{n-data}]
 @end format
 @end cartouche
 
 Data follow the Metadata in the legacy binary format, with sources in
-the same order.  Each NumericSeries begins with a @code{series-name}
+the same order.  Each NumericSeries begins with a @code{variable-name}
 that generally indicates its role in the pivot table, e.g.@: ``cell'',
 ``cellFormat'', ``dimension0categories'', ``dimension0group0'',
-followed by the numeric data, one double per element in the series.  A
-double with the maximum negative double @code{-DBL_MAX} represents the
-system-missing value SYSMIS.
+followed by the numeric data, one double per datum.  A double with the
+maximum negative double @code{-DBL_MAX} represents the system-missing
+value SYSMIS.
 
 @cartouche
 @format
 StringData @result{} i1 string[@t{source-name}] Pairs Labels
 
-Pairs @result{} int[@t{n-string-series}] PairSeries*[@t{n-string-series}]
-PairSeries @result{} string[@t{pair-series-name}] int[@t{n-pairs}] Pair*[@t{n-pairs}]
+Pairs @result{} int[@t{n-string-vars}] PairSeries*[@t{n-string-vars}]
+PairVar @result{} string[@t{pair-var-name}] int[@t{n-pairs}] Pair*[@t{n-pairs}]
 Pair @result{} int[@t{i}] int[@t{j}]
 
 Labels @result{} int[@t{n-labels}] Label*[@t{n-labels}]
@@ -1195,23 +1196,23 @@ Label @result{} int[@t{frequency}] int[@t{s}]
 
 A source may include a mix of numeric and string data values.  When a
 source includes any string data, the data values that are strings are
-set to SYSMIS in the NumericSeries, and StringData follows the
+set to SYSMIS in the NumericData, and StringData follows the
 NumericData.  A source that contains no string data omits the
 StringData.  To reliably determine whether a source includes
 StringData, the reader should check whether the offset following the
-NumericData is the offset of the next series, as indicated by its
+NumericData is the offset of the next source, as indicated by its
 Metadata (or the end of the member, in the case of the last source).
 
 StringData repeats the name of the source (from Metadata).
 
-The string data overlays the numeric data.  @code{n-string-series} is
-the number of series within the source that include string data.  More
-precisely, it is the 1-based index of the last series in the source
+The string data overlays the numeric data.  @code{n-string-vars} is
+the number of variables in the source that include string data.  More
+precisely, it is the 1-based index of the last variable in the source
 that includes any string data; thus, it would be 4 if there are 5
-series and only the fourth one includes string data.
+variables and only the fourth one includes string data.
 
-Each PairSeries consists a sequence of 0 or more Pair nonterminals,
-each of which maps from a 0-based index within series @code{i} to a
+Each PairVar consists a sequence of 0 or more Pair nonterminals, each
+of which maps from a 0-based index within variable @code{i} to a
 0-based label index @code{j}, e.g.@: pair @code{i} = 2, @code{j} = 3,
 means that the third data value (with value SYSMIS) is to be replaced
 by the string of the fourth Label.
@@ -1225,3 +1226,246 @@ label is the string @code{s}.  Each label also includes a
 @section Legacy Detail Member XML Format
 
 This format is still under investigation.
+
+All elements have an optional @code{id} attribute.
+
+@node SPV Detail visualization Element
+@subsection The @code{visualization} Element
+
+@format
+Parent: Document root
+Contents:
+     extension?
+     userSource
+     (sourceVariable @math{|} derivedVariable)@math{+}
+     graph
+     labelFrame@math{+}
+     container?
+     style@math{+}
+     layerController?
+@end format
+
+This element has the following attributes.
+
+@defvr {Required} creator
+The version of the software that created this SPV file, as a string of
+the form @code{xxyyzz}, which represents software version xx.yy.zz,
+e.g.@: @code{160001} is version 16.0.1.  The corpus includes major
+versions 16 through 19.
+@end defvr
+
+@defvr {Required} date
+The date on the which the file was created, as a string of the form
+@code{YYYY-MM-DD}.
+@end defvr
+
+@defvr {Required} lang
+The locale used for output, in Windows format, which is similar to the
+format used in Unix with the underscore replaced by a hyphen, e.g.@:
+@code{en-US}, @code{en-GB}, @code{el-GR}, @code{sr-Cryl-RS}.
+@end defvr
+
+@defvr {Required} name
+The title of the pivot table, localized to the output language.
+
+@defvr {Required} style
+The @code{id} of a @code{style} element (@pxref{SPV Detail style
+element}).  This is the base style for the entire pivot table.  In
+every example in the corpus, the value is @code{visualizationStyle}
+and the corresponding @code{style} element has no attributes other
+than @code{id}.
+@end defvr
+
+@defvr {Required} type
+A floating-point number.  The meaning is unknown.
+@end defvr
+
+@defvr {Required} version
+The visualization schema version number.  In the corpus, the value is
+one of 2.4, 2.5, 2.7, and 2.8.
+@end defvr
+
+@node SPV Detail userSource Element
+@subsection The @code{userSource} Element
+
+@format
+Parent: @code{visualization} @*
+Contents:
+@end format
+
+This element has the following attributes.
+
+@defvr {Optional} missing
+Always @code{listwise}.
+@end defvr
+
+@node SPV Detail sourceVariable Element
+@subsection The @code{sourceVariable} Element
+
+@format
+Parent: @code{visualization} @*
+Contents: @code{extension}* (@code{format} @math{|} @code{stringFormat})?
+@end format
+
+This element defines a variable whose values can be used elsewhere in
+the visualization.  It ties this element's @code{id} to a variable
+from the @file{.bin} member that corresponds to this @file{.xml}.
+
+This element has the following attributes.
+
+@defvr {Required} categorical
+Always set to @code{true}.
+@end defvr
+
+@defvr {Required} source
+Always set to @code{tableData}, the @code{source-name} in the
+corresponding @file{.bin} member (@pxref{SPV Legacy Member Metadata}).
+@end defvr
+
+@defvr {Required} sourceName
+The name of a variable within the source, the @code{variable-name} in
+the corresponding @file{.bin} member (@pxref{SPV Legacy Member Data}).
+@end defvr
+
+@defvr {Optional} dependsOn
+The @code{variable-name} of a variable linked to this one, so that a
+viewer can work with them together.  For a group variable, this is the
+name of the corresponding categorical variable.
+@end defvr
+
+@defvr {Optional} label
+The variable label, if any
+@end defvr
+
+@defvr {Optional} labelVariable
+The @code{variable-name} of a variable whose string values correspond
+one-to-one with the values of this variable and are suitable for use
+as value labels.
+@end defvr
+
+@node SPV Detail derivedVariable Element
+@subsection The @code{derivedVariable} Element
+
+@format
+Parent: @code{visualization} @*
+Contents: @code{extension}* (@code{format} @math{|} @code{stringFormat} @code{valueMapEntry}*)
+@end format
+
+Like @code{sourceVariable}, this element defines a variable whose
+values can be used elsewhere in the visualization.  Instead of being
+read from a data source, the variable's data are defined by a
+mathematical expression.
+
+This element has the following attributes.
+
+@defvr {Required} categorical
+Always set to @code{true}.
+@end defvr
+
+@defvr {Required} value
+An expression that defines the variable's value.  In theory this could
+be an arbitrary expression in terms of constants, functions, and other
+variables, e.g.@: @math{(@var{var1} + @var{var2}) / 2}.  In practice,
+the corpus contains only the following forms of expressions:
+
+@table @code
+@item constant(@var{number})
+@itemx constant(@var{variable})
+A constant.  The meaning when a variable is named is unknown.
+Sometimes the ``variable name'' has spaces in it.
+
+@item map(@var{variable})
+Transforms the values in the named @var{variable} using the
+@code{valueMapEntry}s contained within the element.
+@end table
+@end defvr
+
+@defvr {Optional} dependsOn
+The @code{variable-name} of a variable linked to this one, so that a
+viewer can work with them together.  For a group variable, this is the
+name of the corresponding categorical variable.
+@end defvr
+
+@node SPV Detail valueMapEntry Element
+@subsubsection The @code{valueMapEntry} Element
+
+@format
+Parent: @code{derivedVariable} @*
+Contents: empty
+@end format
+
+A @code{valueMapEntry} element defines a mapping from one or more
+values of a source expression to a target value.  (In the corpus, the
+source expression is always just the name of a variable.)  Each target
+value requires a separate @code{valueMapEntry}.  If multiple source
+values map to the same target value, they can be combined or separate.
+
+@code{valueMapEntry} has the following attributes.
+
+@defvr {Required} from
+A source value, or multiple source values separated by semicolons,
+e.g.@: @code{0} or @code{13;14;15;16}.
+@end defvr
+
+@defvr {Required} to
+The target value.
+@end defvr
+
+@node SPV Detail extension Element
+@subsection The @code{extension} Element
+
+This is a general-purpose ``extension'' element.  Readers that don't
+understand a given extension should be able to safely ignore it.  The
+attributes on this element, and their meanings, vary based on the
+context.  Each known usage is described separately below.  The current
+extensions use attributes exclusively, without any nested elements.
+
+@subsubheading @code{visualization} Parent Element
+
+With @code{visualization} as its parent element, @code{extension} has
+the following attributes.
+
+@defvr {Optional} numRows
+An integer that presumably defines the number of rows in the displayed
+pivot table.
+@end defvr
+
+@defvr {Optional} showGridline
+Always set to @code{false} in the corpus.
+@end defvr
+
+@defvr {Optional} minWidthSet
+@defvrx {Optional} maxWidthSet
+Always set to @code{true} in the corpus.
+@end defvr
+
+@subsubheading @code{container} Parent Element
+
+With @code{container} as its parent element, @code{extension} has the
+following attributes.
+
+@defvr {Required} combinedFootnotes
+Always set to @code{true} in the corpus.
+@end defvr
+
+@subsubheading @code{sourceVariable} and @code{derivedVariable} Parent Element
+
+With @code{sourceVariable} or @code{derivedVariable} as its parent
+element, @code{extension} has the following attributes.  A given
+parent element often contains several @code{extension} elements that
+specify the meaning of the source data's variables or sources, e.g.@:
+
+@example
+<extension from="0" helpId="corrected_model"/>
+<extension from="3" helpId="error"/>
+<extension from="4" helpId="total_9"/>
+<extension from="5" helpId="corrected_total"/>
+@end example
+
+@defvr {Required} from
+An integer or a name like ``dimension0''.
+@end defvr
+
+@defvr {Required} helpId
+An identifier.
+@end defvr