Das Problem: Ein wichtiger Schritt bei der Berechnung der superseded updates ist die Zuordnung von Bundle-RevisionIds, Update-RevisionIds und FileIds. Doch mit der gegenwärtigen Methode stimmt diese Zuordnung manchmal nicht.
Das kann man am besten an einer minimalen Beispieldatei demonstrieren:
Beispiel_1.xml
- Code: Select all
<?xml version="1.0" encoding="utf-8"?>
<OfflineSyncPackage>
<Updates>
<Update RevisionId="50" IsBundle="true" />
<Update RevisionId="49">
<PayloadFiles>
<File Id="a=" />
</PayloadFiles>
<BundledBy>
<Revision Id="50" />
</BundledBy>
</Update>
<Update RevisionId="48">
<PayloadFiles>
<File Id="b=" />
</PayloadFiles>
<BundledBy>
<Revision Id="50" />
</BundledBy>
</Update>
<Update RevisionId="47">
<PayloadFiles>
<File Id="c=" />
</PayloadFiles>
<BundledBy>
<Revision Id="50" />
</BundledBy>
</Update>
<Update RevisionId="46" IsBundle="true" />
<Update RevisionId="45">
<PayloadFiles>
<File Id="d=" />
</PayloadFiles>
<BundledBy>
<Revision Id="46" />
</BundledBy>
</Update>
<Update RevisionId="44">
<PayloadFiles>
<File Id="e=" />
</PayloadFiles>
<BundledBy>
<Revision Id="46" />
</BundledBy>
</Update>
<Update RevisionId="43">
<PayloadFiles>
<File Id="f=" />
</PayloadFiles>
<BundledBy>
<Revision Id="46" />
</BundledBy>
</Update>
<Update RevisionId="42" IsBundle="true" />
<Update RevisionId="41">
<PayloadFiles>
<File Id="g=" />
</PayloadFiles>
<BundledBy>
<Revision Id="42" />
</BundledBy>
</Update>
<Update RevisionId="40">
<PayloadFiles>
<File Id="h=" />
</PayloadFiles>
<BundledBy>
<Revision Id="42" />
</BundledBy>
</Update>
<Update RevisionId="39">
<PayloadFiles>
<File Id="i=" />
</PayloadFiles>
<BundledBy>
<Revision Id="42" />
</BundledBy>
</Update>
</Updates>
</OfflineSyncPackage>
Bundle-Records und Update-Records stehen in der XML-Datei auf derselben Hierarchieebene und sind beide vom Typ "Update". Bundle-Records haben aber das Attribut IsBundle="true", und sie enthalten zusätzliche Informationen zu den nachfolgenden Update-Records.
Update-Records wiederum haben einen Rückverweis "BundledBy" auf den darüberstehenden Bundle-Record. Update-Records enthalten jeweils ein "PayloadFile". Alle Records enthalten noch weitere Elemente, zum Beispiel für die verwendete Sprache, aber diese habe ich für das minimale Beispiel weggelassen.
Die XSLT-Datei ExtractUpdateRevisionAndFileIds.xsl extrahiert nun die RevisionIds und File-Ids. Für die erste Beispieldatei sieht das Ergebnis so aus:
- Code: Select all
$ xmlstarlet transform ExtractUpdateRevisionAndFileIds.xsl Beispiel_1.xml
#50#
#49#,a=
#48#,b=
#47#,c=
#46#
#45#,d=
#44#,e=
#43#,f=
#42#
#41#,g=
#40#,h=
#39#,i=
Danach kommt im Skript eine Schleife, bei der Bundle-RevisionIds und Update-RevisionIds einander zugeordnet werden: Wenn eine RevisionId alleine in einer Zeile steht, dann gilt sie als Bundle-RevisionId und wird an die nachfolgenden Zeilen mit Update-RevisionIds angefügt. Die Datei BundledUpdateRevisionAndFileIds.txt sieht für dieses erste Beispiel dann so aus:
- Code: Select all
#50#
#49#,a=;#50#
#48#,b=;#50#
#47#,c=;#50#
#46#
#45#,d=;#46#
#44#,e=;#46#
#43#,f=:#46#
#42#
#41#,g=;#42#
#40#,h=;#42#
#39#,i=;#42#
Allerdings kann auch ein Bundle-Record Referenzen für EulaFiles enthalten. Wenn man ein solches Element in den Bundle-Record mit der RevisionId 46 einfügt, sieht die Beispieldatei so aus:
Beispiel_2.xml
- Code: Select all
<?xml version="1.0" encoding="utf-8"?>
<OfflineSyncPackage>
<Updates>
<Update RevisionId="50" IsBundle="true" />
<Update RevisionId="49">
<PayloadFiles>
<File Id="a=" />
</PayloadFiles>
<BundledBy>
<Revision Id="50" />
</BundledBy>
</Update>
<Update RevisionId="48">
<PayloadFiles>
<File Id="b=" />
</PayloadFiles>
<BundledBy>
<Revision Id="50" />
</BundledBy>
</Update>
<Update RevisionId="47">
<PayloadFiles>
<File Id="c=" />
</PayloadFiles>
<BundledBy>
<Revision Id="50" />
</BundledBy>
</Update>
<Update RevisionId="46" IsBundle="true">
<EulaFiles>
<File Id="xxx=" />
</EulaFiles>
</Update>
<Update RevisionId="45">
<PayloadFiles>
<File Id="d=" />
</PayloadFiles>
<BundledBy>
<Revision Id="46" />
</BundledBy>
</Update>
<Update RevisionId="44">
<PayloadFiles>
<File Id="e=" />
</PayloadFiles>
<BundledBy>
<Revision Id="46" />
</BundledBy>
</Update>
<Update RevisionId="43">
<PayloadFiles>
<File Id="f=" />
</PayloadFiles>
<BundledBy>
<Revision Id="46" />
</BundledBy>
</Update>
<Update RevisionId="42" IsBundle="true" />
<Update RevisionId="41">
<PayloadFiles>
<File Id="g=" />
</PayloadFiles>
<BundledBy>
<Revision Id="42" />
</BundledBy>
</Update>
<Update RevisionId="40">
<PayloadFiles>
<File Id="h=" />
</PayloadFiles>
<BundledBy>
<Revision Id="42" />
</BundledBy>
</Update>
<Update RevisionId="39">
<PayloadFiles>
<File Id="i=" />
</PayloadFiles>
<BundledBy>
<Revision Id="42" />
</BundledBy>
</Update>
</Updates>
</OfflineSyncPackage>
Die XSLT-Datei ExtractUpdateRevisionAndFileIds.xsl unterscheidet allerdings nicht zwischen PayloadFiles und EulaFiles. Beide haben eine FileId, und alle FileIds werden gleichermaßen ausgegeben. Damit sieht die Ausgabe so aus:
- Code: Select all
$ xmlstarlet transform ExtractUpdateRevisionAndFileIds.xsl Beispiel_2.xml
#50#
#49#,a=
#48#,b=
#47#,c=
#46#,xxx=
#45#,d=
#44#,e=
#43#,f=
#42#
#41#,g=
#40#,h=
#39#,i=
Nach der Zuordnung von Bundle-RevisionIds und Update-RevisionIds in der anschließenden Programmschleife hat die Datei BundledUpdateRevisionAndFileIds.txt den Inhalt:
- Code: Select all
#50#
#49#,a=;#50#
#48#,b=;#50#
#47#,c=;#50#
#46#,xxx=;#50#
#45#,d=;#50#
#44#,e=;#50#
#43#,f=;#50#
#42#
#41#,g=;#42#
#40#,h=;#42#
#39#,i=;#42#
Der Bundle-Record 46 wird nun als Update-Record interpretiert. Die Bundle-RevisionId 46 wird unterschlagen und in der weiteren Auswertung nicht mehr berücksichtigt. Statt dessen wird die Bundle-RevisionId 50 an die Zeile mit dem Bundle-Record 46 und an die drei nachfolgenden Zeilen mit Update-Records angefügt.
Da die Bundle-Records bestimmen, welche Dateien als superseded gelten, kann es am Ende zu Unstimmigkeiten kommen.