a 'mooh' point

clearly an IBM drone

Bit-masks i OOXML

Når kampen for OOXML og ODF er så meget op ad bakke skyldes det i høj grad usikkerhed om, hvad der rent faktisk er fakta i diskussionen. Én af kilderne til denne usikkerhed er desværre Grokdoc.net. Når jeg skriver "desværre" er det fordi Grokdoc har lavet en ganske omfattende gennemgang af specifikationen for OOXML (hvilket jo i sig selv piller ved argumentet om, at den er for stor til at nogen andre end Microsoft kan overskue den), men den er desværre også fejlbehæftet. De fejlbehæftede dele er ikke så store - problemet ligger i, at det netop er disse fejlantagelser, der bliver brugt som primære argumenter imod OOXML som standard.

Én af disse fejl er de såkalte "bit-masks".

Der er såmænd ikke så meget forkert i selve observationen af, at der er bitmasks i OOXML-spec. Problemet ligger i, at problematikken i deres tilstedeværelse overdrives, ja Rick Jelliffe fra O'Reilly går så langt som at sige: "Some of the technical claims are silly (such as the "bitmask rubbish").

Grokdoc definerer en "bitmask" som:

"A bitmask is a technique to encode multiple values inside a single variable, by assigning a meaning to each individual bits of the variable. For example, the binary 10110001 (decimal 177) would mean Yes/No/Yes/Yes/No/No/No/Yes and contain the answers to 8 different yes/no questions." Grokdoc inkluderer herefter en liste over de steder i OOXML-spec, der omhandler bitmasks af forskellig art.

OOXML indeholder en række eksempler på anvendelsen af disse bitmasks. Ét af eksemplerne er fra sektion 2.8.2.16 for attribut usb1:

[Example: Consider font information specified as follows:
<w:font w:name="Times New Roman">
<w:sig w:usb2="00000008" … />

</w:font>
The usb0 attribute value of 80000000 specifies that the first 32 bits of the bitfield are
00000000000000000000000000001000, which corresponds to:
Arabic Presentation Forms-B
end example]

Læg her mærke til, at bitmasken er en string-repræsentation af en Hex'et bitværdi.

Et andet eksempel som jeg selv er faldet over tidligere (men ikke er nævnt på Grokdoc) er fra afsnit 2.8.11 ST_Cnf (Conditional Formatting Bitmask):

Fra OOXML-spec har jeg klippet følgende forklaring:

10 This simple type specifies the format for the set of conditional formatting properties that have been applied to
11 this object.
12 These properties are expressed using a string serialization of a binary bitmask for each of the following
13 properties (reading from the first character position right):

[Example: Consider a paragraph in the top right corner of a table with a table style applied. This paragraph
35 would need to specify the following WordprocessingML:
36 <w:p>
37   <w:pPr>
38     <w:cnfStyle w:val="101000000100" />

1       …
2     </w:pPr>
3     …
4 </w:p>
5 This paragraph specifies that it has the conditional properties from the table style for the first column, first row,
6 and the NW corner of the parent table by setting the appropriate bits in the val attribute. end example]

Grokdoc har følgende indvendinger overfor anvendelsen af disse bitmasks:

1.Bitmasks cause significant validation problems

Using bitmasks creates a new data model, separate from the XML data model. In particular, the bitmask cannot be described in or validated by XML Schema, Relax NG, Schematron or any standard XML schema language or current validator.

Selve bitmask-værdien er en ganske almindelig element-attribut og OOXML-spec beskriver endda, at indholdet af denne her skal matche det regulære udtryk [01]* . At sige at det ikke kan lade sig gøre at validere denne værdi er en pudsig anke imod OOXML, da man jo heller ikke kan validere andre (komplekse) værdier i en XML-fil for mening. Selvom jeg anvendte enums i mit XML-schema ville jeg ikke kunne validere om det enkelte "1" eller "0", hhv "true" eller "false" rent faktisk gav mening.

2. Bitmasks defeat XSLT manipulation

XSLT is the W3C standard for manipulating and converting XML documents, and is by far the most popular tool for working with XML. XSLT has no tools for bitwise operators, since bitmasks are not part of the XML data model.

Det er vigtigt at understrege, at bitmaskerne er reelt bit-flag, der ikke er relaterede til hinanden. Det er også vigtigt at understrege, at bitmasken ikke er "en række bits" men derimod en serialisering af en række flag. Derfor giver det ikke mening at tale om, at XSLT ikke kan anvendes på disse bitflag, da XSLT ikke indeholder mulighed for "bitwise operators". Bitwise operators er jo noget med OR, AND, XOR, NAND etc, men det giver slet ikke mening at tale om dette i denne kontekst. Hvis OOXML-spec i stedet havde udskilt disse 12 formatteringsflag i selvstændige attributter/elementer med mønstret [true,false] ville det have været nøjagtigt lige så nemt/svært at manipulere disse værdier som det er nu i bitmasken, som jeg hellere vil benævne en "short-hand positioning-definition" end en "bitmaske". At omtale disse flag som bits forvirrer mere end det gavner (man kan sige, at OOXML har skudt sig selv i foden ved at benævne dem som "bitmasks").

3. Bitmasks conflict with the Ecma TC45 charter

The TC45 is the Ecma Technical Committee charged with developing the Ecma 376 specification. The charter of the TC45 includes the specific goal of: "...enabling the implementation of the Office Open XML Formats by a wide set of tools and platforms in order to foster interoperability across office productivity applications and with line-of-business systems"

Since bitmasks cannot be implemented in any of the standard tools for XML data formats, their use is in conflict with the TC45's charter.

Er dette ikke liiige at stramme den? For det første er værktøjerne til manipulering af OOXML ikke kun indsnævret til XML-værktøjer som XSLT. For det andet er der intet i disse eksempler på bitflag, der afholder manipulering af dem fra at blive implementeret i XSLT. Man kan argumentere for, at bitflagene ikke er specielt "XML-agtige", men at bruge dette som argument for at afvise standarden er i mine øjne for langt ude.

4. Bitmasks are not extensible

The bitmasks specified by Ecma 376 are mostly of fixed length (a fixed number of bits). For example, the bitmasks used in sections 2.4.51, 2.4.52, 2.15.1.86, and 2.15.1.87 are all of type ST_ShortHexNumber (2.18.86, p. 2591), which is defined as consisting of exactly 4 hexadecimal digits (16 bits, see above regarding conflicting definitions). The bitmasks in section 2.8.2.16 are of type ST_LongHexNumber (2.18.57, p. 2542) which is defined as consisting of exactly 8 hexadecimal digits (32 bits, see above regarding conflicting definitions). The bitmasks in sections 2.3.1.8, 2.4.7, and 2.4.8 are of type ST_Cnf (2.18.11, p. 2478), which is defined as consisting of exactly 12 binary digits (12 bits). The bitmask in section 6.1.2.7 (p. 5227) consists of exactly "three bits".

Because it is not possible to add new bits to a fixed-length bitmask, extensibility is extremely limited.

Jeg kan godt forstå, hvorfor Grokdoc ønsker denne mulighed, for det er netop én af arkitekturprincipperne for ODF - nemlig muligheden for at udvide spec'en afhængigt at applikationen. Pudsigt nok er den manglende mulighed for applikationsspecifik udvidelse netop ét af grundprincipperne for OOXML. Argumentet fra OOXML er, at det er svært at sikre interoperabilitet, når hver implementering af formatet kan udvide dette som man lyster. Var det her muligt at udvide en af bitflagsrækkerne med ekstra flag - hvordan skulle andre applikationer kunne anvende dette? Dette er ét af en række eksempler på, hvordan en arkitekturbeslutning påvirker den konkrete implementering af den. Diskussionen om disse flag bør altså reelt ikke dreje sig om deres eksistens men derimod om hvilket arkitekturprincip, der bør ligge bag formatet.

 

Comments (9) -

Christian Schmidt

Jeg er novice udi XSLT, så bær over med mig, hvis jeg vrøvler alt for meget i det følgende.

>2. [...] Bitwise operators er jo noget med OR, AND, XOR, NAND etc, men
>det giver slet ikke mening at tale om dette i denne kontekst.
Jeg er uenig. Man kan godt lave bitlogik på en hel bitmaske ad gangen, fx b10001001 & b11000001 = b10000001.


Antag at et fiktivt format tillader, at man kan skrive flg.:
Her er &lt;foo bold="true">fed&lt;/foo> og &lt;foo italic="true">kursiv&lt;/foo> tekst.

Vha. XLT kan dette transformeres til HTML vha. regler i stil med flg.:

&lt;xsl:template match="foo[@bold='true']">
  &lt;b>
    &lt;xsl:apply-templates/>
  &lt;/b>
&lt;/xsl:template>
&lt;xsl:template match="foo[@italic='true']">
  &lt;i>
    &lt;xsl:apply-templates/>
  &lt;/i>
&lt;/xsl:template>


Dette kan ikke lade sig gøre, hvis fed og kursiv blev angivet vha. bitmasker, fx "10" for fed, "01" for kursiv og "11" for fed+kursiv. Da vil man have behov for at kunne skrive noget i retning af flg., hvilket man vistnok ikke kan i XSLT:
&lt;xsl:template match="foo[@format & 10]">
  &lt;b>
    &lt;xsl:apply-templates/>
  &lt;/b>
&lt;/xsl:template>
&lt;xsl:template match="foo[@format & 01]">
  &lt;i>
    &lt;xsl:apply-templates/>
  &lt;/i>
&lt;/xsl:template>

Christian Schmidt

<p>Jeg er novice udi XSLT, så bær over med mig, hvis jeg vrøvler alt for meget i det følgende.</p>
<p>>2. [...] Bitwise operators er jo noget med OR, AND, XOR, NAND etc,<br>
>men det giver slet ikke mening at tale om dette i denne kontekst.
Jeg er uenig. Man kan godt lave bitlogik på en hel bitmaske ad gangen, fx b10001001 & b11000001 = b10000001.</p>
<p>
Antag at et fiktivt format tillader, at man kan skrive flg.:<br>
Her er &lt;foo bold="true">fed&lt;/foo> og &lt;foo italic="true">kursiv&lt;/foo> tekst.</p>
<p>Vha. XLT kan dette transformeres til HTML vha. regler i stil med flg.:</p>
<pre>
&lt;xsl:template match="foo[@bold='true']">
  &lt;b>
    &lt;xsl:apply-templates/>
  &lt;/b>
&lt;/xsl:template>
&lt;xsl:template match="foo[@italic='true']">
  &lt;i>
    &lt;xsl:apply-templates/>
  &lt;/i>
&lt;/xsl:template></pre>
<p>Dette kan ikke lade sig gøre, hvis fed og kursiv blev angivet vha. bitmasker, fx "10" for fed, "01" for kursiv og "11" for fed+kursiv. Da vil man have behov for at kunne skrive noget i retning af flg., hvilket man vistnok ikke kan i XSLT:</p>
<pre>&lt;xsl:template match="foo[@format & 10]">
  &lt;b>
    &lt;xsl:apply-templates/>
  &lt;/b>
&lt;/xsl:template>
&lt;xsl:template match="foo[@format & 01]">
  &lt;i>
    &lt;xsl:apply-templates/>
  &lt;/i>
&lt;/xsl:template></pre>

Hvordan indsætter man linjeskift i sit indlæg?

>4. [...] Pudsigt nok er den manglende mulighed for
>applikationsspecifik udvidelse netop ét af grundprincipperne
>for OOXML.
Der behøver ikke at være tale om applikationsspecifikke udvidelser. "extensibility" er også relevant, hvis man ønsker at specificere nye versioner af formatet (OOXML version 2), men samtidig ønsker at bevare bagudkompatibilitet, således at ældre software kan åbne nye filer, selvom det ikke forstår betydningen af alle attributter og tags.

> Jeg er uenig. Man kan godt lave bitlogik på en hel bitmaske ad gangen, fx
> b10001001 & b11000001 = b10000001.

Ja - men det er heller ikke mit argument. Mit argument er, at det ikke er nødvendigt at lave binære operationer på bitmasken for at sætte de enkelte flad. Hvis bitmasken krævede binære operationer på bitmasken, var det et helt andet problem.

Jeg er faktisk senere faldet over et sted i OOXML, hvor det netop er krævet at lave de binære operationer. Afsnittene er fx 2.8.2.16,  

> Jeg er uenig. Man kan godt lave bitlogik på en hel bitmaske ad
> gangen, fx b10001001 & b11000001 = b10000001.

Ja - men det er heller ikke mit argument. Mit argument er, at det ikke er nødvendigt at lave binære operationer på bitmasken for at sætte de enkelte flag. Hvis bitmasken krævede binære operationer på bitmasken, var det et helt andet problem. Jeg er dog faktisk senere faldet over et sted i OOXML, hvor det netop er krævet at lave de binære operationer. Afsnittene er fx 2.8.2.16 og 2.4.52, hvor det for mig ser ud til, at håndteringen af disse hex-bitmasker indebærer binær logik.

Det er naturligvis noget hø og skal fjernes.

Mht extensibility, så er det imo en smagssag. I mine øjne er det ikke meget sværere at håndtere en bitmaske af fast længde på 12, der i næste version bliver med fast længde på 14 end det er at håndtere en udvidelse af det underliggende schema, der definerer det valide elementer og attributter. Vi kan godt blive enige om, at det er "mest xml-agtigt" at lave bitmasken som en række elementer/attributter, men jeg mener ikke, at det er et stort problem.

Mht linieskift ... jeg skal nok lige kigge efter det :o)

>Mit argument er, at det ikke er nødvendigt at lave binære
>operationer på bitmasken for at sætte de enkelte flag.
Hvordan vil du så skrive en XSLT, der omdanner fra OOXML til fx HTML? Eller for den sags skyld en XSLT, der blot flipper en bit i en eksisterende OOXML-fil? Pointen er vel, at XSLT ikke kan gøre meget andet ved en bitmaske end at fjerne den eller føre den uændret igennem.

(tænke, google, pille næse)

Og dog - mon ikke man med lidt snilde kan lave noget med substring().

Jeg har endnu til gode at se lyset mht. XSLT ...


>I mine øjne er det ikke meget sværere at håndtere en bitmaske
>af fast længde på 12, der i næste version bliver med fast
>længde på 14 end det er at håndtere en udvidelse af det
>underliggende schema, der definerer det valide elementer og
>attributter.
Problemet opstår, når en OOXML1-fortolker falder over et OOXML2-dokument, hvor en attribut pludselig indeholder 14 bits mod de forventede 12. Skal den så kigge på de 12 første eller de 12 sidste bits, eller skal den helt ignorere attributten?

Men det kan man selvfølgelig specificere sig ud af vha. et pennestrøg, og det synes jeg, man bør gøre (det er fjollet at lade være).

Man må vel forvente, at man vælger at udvide formatet på en sådan bagudkompatibel måde, når der kommer nye revisioner, frem for at lancere et helt nyt format, som slet ikke kan åbnes af ældre software. Man har mig bekendt gjort noget tilsvarende med .doc-formatet.


Tak for rettelse af linjeskift Smile

> Og dog - mon ikke man med lidt snilde kan lave noget med substring().

Ja - det var præcist min tanke. Det er muligt med substring-metoderne at gøre det ønskede.

> Jeg har endnu til gode at se lyset mht. XSLT ...

Jeg har det med XSLT som med SQL (som jeg i parentes bemærket er markant bedre til at mestre end XSLT) at det er et utroligt undervurderet værktøj. Jeg hører ofte novicer udtale, at SQL "jo bare gør det muligt at udtrække nogle data fra en database" og det er jo en grov undervurdering af SQLs anvendelsesmulighed. På samme måde har jeg det med XSLT, der i kraftfuldhed jo slet ikke hyldes nok, når man siger "XSLT kan jo bare flytte lidt rundt på noget XML-data".

... til listen kan i øvrigt også lægges regulære udtryk Smile

PS: som du kan se, så har jeg ikke fixet linieskift ...

... men det virker åbenbart i IE

(skod-blog-engine)

Smile

Comments are closed