Model adresování konvencí otevřeného balení

 

David Meltzer a Andrey Shur
Microsoft Corporation

Červen 2006

Platí pro:
   Otevřené konvence balení
   Microsoft Office 2007
   Microsoft Windows Vista
   Microsoft .NET Framework

Shrnutí: Tento článek poskytuje přehled modelu adresování používaného v konvencích open packaging, včetně toho, jak jsou balíčky a jejich části adresovány, jak se řeší relativní odkazy v částech balíčků a jak můžou aplikace využívat model adresování balíčků pomocí rozhraní .NET Framework a tříd. (16 vytištěných stránek)

Obsah

Předmluva
Model adresování
Podpora programování pro identifikátory URI "pack:"
Reference

Předmluva

Jako součást návrhu Sady Office 2007 a Windows Vista společnost Microsoft představila konvence otevřených balíčků. Tyto konvence popisují, jak lze obsah uspořádat do "balíčku". Mezi příklady obsahu patří dokument, kolekce médií a knihovna aplikací. Balíčky agregují všechny komponenty obsahu do jednoho objektu.

Aplikace pro zpracování textu může používat balíčky, například k ukládání stránek dokumentu, potřebných písem a obrázků, grafů a poznámek na stránkách. Aplikace pro prohlížení nebo správu dokumentů může v balíčku zobrazovat jenom části obsahu. Aplikace můžou k odesílání obsahu a prostředků s pevným rozložením do tiskárny používat formát založený na balíčcích, například FORMÁT XPS (XML Paper Specification).

Tento článek poskytuje přehled modelu adresování, který se používá v konvencích otevřených balíčků, včetně toho, jak jsou balíčky a jejich části adresovány a jak se řeší relativní odkazy v částech balíčků. Tento článek také popisuje, jak mohou aplikace využívat model adresování balíčků pomocí tříd rozhraní .NET Framework a .NET Framework 3.0. Tento článek je určen především pro vývojáře aplikací, které budou zpracovávat, vytvářet nebo využívat balíčky.

Úplné normativní informace potřebné k implementaci modelu adresování balíčků najdete ve specifikaci konvencí otevřeného balení. Sady SDK rozhraní .NET Framework 3.0 a .NET poskytují další informace o probíraných třídách a metodách.

Materiál uvedený v tomto přehledu předpokládá základní znalost specifikace identifikátoru URI. Podle RFC 3986 se používají následující termíny: identifikátor URI, odkaz na identifikátor URI, komponenta schématu, komponenta autority, komponenta cesty, absolutní cesta a relativní odkaz. Termín URI vždy označuje absolutní formu identifikátoru URI – je k dispozici komponenta schématu a všechny ostatní komponenty odpovídají gramatikě specifické pro schéma. Termín adresovatelný, jak se zde používá, označuje, že existuje identifikátor URI, který identifikuje prostředek.

Model adresování

Open Packaging Conventions definují logický model pro uspořádání obsahu a prostředků balíčku a poskytují mapování z tohoto logického modelu na fyzickou reprezentaci založené na ZIP, XML a dalších veřejně dostupných technologiích.

Logický model balení popsaný v otevřených konvencích balení definuje abstrakci balíčku, který obsahuje kolekci částí. Části můžou mít vztahy mezi sebou a balíček může mít relace k částem. Model balení určuje, jak jsou části v balíčku pojmenovány, odkazovány a související. Model adresování definovaný konvencemi je základem pro schopnost odkazovat na a získávat dílčí prostředky v balíčku.

Adresovatelné prostředky balíčku

Instance balíčku jako celek je adresovatelný prostředek, stejně jako každá část uložená v instanci balíčku.

Adresování balíčku jako jednotky

Aplikace můžou použít identifikátor URI s libovolným schématem (například http:, ftp: atd.) k adresování balíčku jako jednotky a získat datový proud bitů tvořících celý balíček.

Aplikace můžou balíček adresovat také pomocí schématu identifikátoru URI pack:" definovaného konvencemi open packaging. Toto schéma určuje, že úplný identifikátor URI identifikující balíček je uložen v komponentě autority identifikátoru URI "pack:" v zakódované podobě.

Příklad: Adresování balíčku

Prostředek balíčku je adresován identifikátory URI "http:" a "pack:" (v uvedeném pořadí) v následujících příkladech:

http://www.site.com/windows/p1.xps

pack://http%3a,,www.site.com,windows,p1.xps/

Typ MIME získaného prostředku balíčku označuje formát souboru balíčku – může to být například formát XPS Document (.xps), formát Office Open XML (.docx) nebo jiný formát, který odpovídá zásadám Open Packaging Conventions.

Z různých důvodů (například zvýšení výkonu) můžou aplikace používat identifikátor URI specifický pro jejich doménu jako součást autority identifikátoru URI pack:. Takový identifikátor URI je možné přeložit pouze v kontextu dané aplikace. Programovací technika používaná pro takové identifikátory URI specifické pro aplikaci je popsána dále v části "The PackageStore".

Adresování částí v rámci balíčku

Části v balíčku jsou adresovány pomocí identifikátorů URI pack:. Struktura identifikátoru URI pack:, který řeší část, je následující: cesta pack://< authority><>

Příklad: Adresování částí

pack://http%3a,,www.site.com,windows,p1.xps/fonts/arial.ttf řeší část s názvem /fonts/arial.ttf v balíčku adresovaném nástrojem http://www.site.com/windows/p1.xps.

Komponenta autority obsahuje kódovaný identifikátor URI celého balíčku. komponenta path obsahuje název části v daném balíčku. Názvy částí odpovídají gramatice definované pro komponentu path-absolute URI ([2], oddíl 3.3) s některými dalšími omezeními ([1], oddíl 2.1.1.1).

Příklad: Názvy částí

/documents/doc1.xaml

/pages/page4.xaml

/fonts/arial.ttf

Názvy částí jsou řetězce ASCII bez rozlišování velkých a malých písmen. Všechny části balíčku mají jedinečné názvy.

Použití identifikátorů fragmentů k odkazům na části

Některé aplikace používající konvence otevřeného balení můžou odkazovat na část pomocí identifikátoru URI, který není pack:" jednotky balíčku s identifikátory fragmentu specifické pro formát.

Příklad: Použití identifikátoru URI jiného než pack:" pro odkaz na část

Identifikátor URI http://www.site.com/windows/p1.xps\#15 se používá k odkazu na část, která představuje stránku 15 v dokumentu p1.xps ([3], oddíly 9.2.2 a 9.2.3).

I když je platný a pro určité scénáře je užitečné, aby identifikátory URI, které nejsou "pack:", odkazovaly na části, nelze tyto identifikátory URI použít jako základní identifikátory URI k překladu relativních odkazů v obsahu součásti.

Odkazy na položky v částech

Část je nejpodrobnější adresovatelný prostředek v rámci balíčku. Aplikace však mohou potřebovat odkazovat na položky v obsahu části. U určitých typů obsahu lze na položky odkazovat pomocí identifikátorů fragmentů ([2], oddíl 3.5). Konvence otevřeného balení neurčovaly identifikátory fragmentů. Aplikace používající identifikátory fragmentů jsou zodpovědné za jejich správné zpracování.

Příklad: Odkazování na položky v částech

pack://http%3a,,www.site.com,windows,p1.xps/pages/page1.xaml#//[@Id="A012"] odkazuje na sadu uzlů XML v obsahu části s názvem /pages/page1.xaml, která má hodnotu atributu IdA012.

Vnořené balíčky

Balíčky mohou být vnořené. Část balíčku může obsahovat obsah libovolného typu, včetně celého balíčku. Části vnořeného balíčku lze adresovat pomocí identifikátoru URI pack:s komponentou autority, která označuje část, která tento vnořený balíček obsahuje ([1], dodatek D.3).

Příklad: Adresování částí ve vnořených balíčcích

Balíček umístěný na adrese http://www.site.com/package obsahuje část s názvem /vnořený-package.

,

adresovaný balíčkem identifikátoru URI "pack:" ://http%3a,,www.site.com,package/nested-package.

Část adresovaná předchozím identifikátorem URI obsahuje jednotku balíčku, která obsahuje část s názvem /p1.xaml.

Adresa této části vnořeného balíčku je následující:

pack://pack%3a,,http:%253a%2c%2cwww.site.com%2cpackage,nested-package/p1.xaml.

Odkazy v obsahu části

Části s určitými typy obsahu, například XML, můžou obsahovat odkazy na identifikátor URI. Odkazy na identifikátory URI můžou být URI nebo relativní odkazy. Odkazy na identifikátor URI mohou být v obsahu reprezentovány řetězci Unicode. Aplikace, které přeloží takové odkazy URI, musí převést řetězce na formulář identifikátoru URI ([4], oddíl 3.1).

Relativní odkaz je identifikátor URI, který je vyjádřen vzhledem k základnímu identifikátoru URI obsahu obsahujícího odkaz. Výchozí základní identifikátor URI pro obsah části je identifikátor URI pack:, který adresuje část.

Příklad: Základní identifikátor URI

Základní identifikátor URI pro část s názvem /pages/page1.xaml v balíčku adresovaném uživatelem http://www.site.com/windows/p1.xps je následující:

pack://http%3a,,www.site.com,windows,p1.xps/pages/page1.xaml.

Pokud je k překladu relativních odkazů v položkách obsahu součásti potřeba alternativní základní identifikátor URI, musí aplikace tento alternativní identifikátor explicitně zadat. Konkrétní typy obsahu zveřejňují určité způsoby určení alternativního základního identifikátoru URI. Například XML používá xml:base atribut, HTML používá <element base> a Open Packaging Conventions používá atribut TargetMode pro elementy Relationship .

Použití identifikátoru URI "pack:" části jako základního identifikátoru URI pro relativní odkaz zaručuje, že odkazovaný prostředek bude součástí stejného balíčku ([2], oddíl 5.2), pokud relativní odkaz není ve zřídka používaném formuláři síťové cesty (tj. relativní odkaz začínající na "//").

Příklad: Překlad relativního odkazu

Relativní odkaz .. /.. /page2.xaml v části adresované jako pack://http%3a,,www.site.com,windows,p1.xps/pages/page1.xaml se přeloží na pack://http%3a,,www.site.com,windows,p1.xps/page2.xaml a řeší část s názvem /page2.xaml.

Producenti balíčků mohou používat názvy částí jako platnou formu relativních odkazů. Při používání názvů částí jako relativních odkazů by však výrobci měli zvážit, zda lze odkazované části adresovat také jako extrahované prostředky mimo balíček. Po extrahování částí z balíčku nemusí být názvy součástí použité jako relativní odkazy přeloženy podle očekávání. Povinné lomítko u názvů částí, určené gramatikou názvu části, znamená, že tyto relativní odkazy jsou přeloženy z kořene aktuální autority.

Příklad: Adresování extrahovaných prostředků

V obsahu části s názvem /doc1/pages/page1.xaml relativní odkaz /page2.xaml řeší část s názvem /page2.xaml a relativní odkaz ./page3.xaml řeší část s názvem /doc1/pages/page3.xaml.

Po extrahování částí /doc1/pages/page1.xaml, /doc1/pages/page3.xaml a /part2.xaml z balíčku do souborů s názvy file:///c:/mydocs/doc1/pages/page1.xaml, file:///c:/mydocs/doc1/pages/page3.xaml a file:///c:/mydocs/page2.xaml (v uvedeném pořadí), relativní odkaz ./page3.xaml adresuje soubor file:///c:/mydocs/doc1/pages/page3.xaml, což se očekává; relativní odkaz /page2.xaml ale teď řeší soubor s názvem file:///page2.xaml.

Relativní odkazy v relacích

Konvence otevřeného balení definují propojení mezi zdrojovou a cílovou částí v balíčku jako relace ([1], oddíl 1.3).

Relace se seskupují a ukládají na základě svých zdrojů. Část relace obsahuje relace, které pocházejí ze stejné zdrojové části. Každá relace je popsána elementem XML v obsahu této části relací. Část relace je jedinečně přidružena k této zdrojové části (a naopak) pomocí definované konvence vytváření názvů pro část relací.

Výchozí základní identifikátor URI pro identifikátory URI zadané v jednotlivých elementech Relationship je identifikátor URI pack:" zdrojové části ([1], oddíl 1.3.5). Atribut TargetMode elementu Relationship označuje základní identifikátor URI pro zadanou relaci.

Příklad: Element Relationship

Element v části relací, který definuje relaci ze zdrojové části s názvem /pages/page1.xaml k cílové části /fonts/arial.ttf v rámci stejného balíčku, může vypadat takto:

<Typ relace="https://schemas.microsoft.com/xps/2005/06/restricted-font"

TargetMode="Internal" Id="A123" Target=".. /fonts/arial.ttf"/>

Hodnota Internal atributu TargetMode označuje, že základní identifikátor URI elementu Relationship je výchozí pro obsah části relace a stejný jako identifikátor URI "pack:" zdrojové části relací. V předchozím příkladu je základní identifikátor URI elementu Relationship identifikátor URI pack:části /pages/page1.xaml .

Relace mohou také cílit na externí prostředky vzhledem k umístění celého balíčku.

Příklad: Vztah k externímu cíli

Pro balíček umístěný v file:///c:/office12/sample.docxelement XML

<ID relace="rId9"

Type="https://schemas.microsoft.com/office/2006/relationships/image"

Target="Icon.JPG" TargetMode="External"/>

definuje relaci, která cílí na soubor file:///c:/office12/icon.jpg.

Hodnota External atributu TargetMode určuje, že relace musí cílit na prostředek mimo balíček. Pokud atribut Target obsahuje relativní odkaz, vyžaduje se základní identifikátor URI. Základní identifikátor URI pro tento element relace musí být identifikátor URI celého balíčku.

Delegování odkazů na relace

Některé formáty založené na balíčku se můžou vyhnout použití odkazů URI v obsahu a delegování odkazů na relace. Tato technika delegování je založená na použití jedinečných hodnot ID u každého elementu Relationship k mapování relativních odkazů v obsahu části na odpovídající relace.

Příklad: Mapování relativních odkazů v obsahu části na relace

Balíček umístěný v file:///c:/office12/sample.docx má část s názvem /word/document.xml , která obsahuje

<a:blip relEmbed="rId6" relLink="" w="0" h="0"/>.

Část relace připojená k této části obsahuje prvek.

<ID relace="rId6"

Type="https://schemas.microsoft.com/office/2006/relationships/image"

TargetMode="Internal" Target="media/image1.jpeg"/>.

Tím provážete element na část s názvem /word/media/image1.jpeg.

Výhodou tohoto přístupu je, že aplikace dokáže identifikovat a udržovat všechny odkazy v rámci balíčku, aniž by se dívala na obsah v částech.

Pokud jsou však odkazy delegovány na relace, nemusí součásti balíčku extrahované do volných souborů správně fungovat. Aby cíle relací fungovaly po extrakci, bude aplikace, která využívá, vyžadovat zvláštní znalosti o relacích, otevřených konvencích balení pro části vztahů a definici základních identifikátorů URI pro soubory relací.

Podpora programování pro identifikátory URI "pack:"

Aplikace vytvářející a/nebo spotřebovávají balíčky budou pracovat s adresami balíčků a částí a přeloží relativní odkazy v obsahu částí. Rozhraní .NET Framework 3.0, které poskytuje sadu spravovaných rozhraní API nové generace od Microsoftu, obsahuje třídy, které podporují model adresování konvencí otevřených balíčků. Tyto třídy umožňují aplikacím vytvářet a parsovat odkazy a získávat prostředky balíčku. Třída PackUriHelper se používá k usnadnění zpracování identifikátorů URI "pack:". Třída PackWebRequest se používá k získání prostředků adresovaných pomocí identifikátorů URI pack:.

Tato část znázorňuje funkce, které tyto služby provádějí při vytváření, parsování a překladu odkazů.

Zpřístupnění služeb balíčků

Rozhraní .NET Framework verze 3.0 (nebo vyšší) musí být nainstalováno, aby bylo možné používat třídy služeb balení. Třídy najdete v oboru názvů System.IO.Packaging .

Před použitím System.Uri pro operace, ve kterých jsou zahrnuty identifikátory URI pack:, musí být schéma identifikátoru URI pack:" zaregistrované pro doménu aplikace. Nejjednodušší způsob, jak zaregistrovat schéma identifikátoru URI "pack:", je volání libovolné metody třídy PackUriHelper . Schéma lze také zaregistrovat bez volání pomocné třídy pomocí metody UriParser.Register , jak je znázorněno v následujícím příkladu. Použití této metody však vyžaduje oprávnění zabezpečení.

Příklad: Registrace schématu identifikátoru URI pack:

//To register the "pack:" URI scheme without calling PackUriHelper

UriParser.Register(new GenericUriParser
   (GenericUriParserOptions.GenericAuthority),
      "pack", -1);

Získání identifikátoru URI "pack:" cílového prostředku

Při využívání balíčku lze jako objekt získat celý balíček nebo jeho část. V obou případech je možné použít metodu PackUriHelper.Create k vytvoření identifikátoru URI balíčku nebo části prostředku. Tento identifikátor URI pack:" se pak předá metodě PackWebRequest , aby bylo možné získat prostředek. BalíčekWebRequest je podrobněji popsán v další části Získání prostředků balíčku pomocí PackWebRequest.

Běžný příklad, jak PackUriHelper a PackWebRequest třídy lze použít k podpoře využití balíčku, je podrobně popsán v následujících krocích. Pokud je identifikátor URI balíčku a část identifikátoru URI známé, aplikace může:

  1. Vytvořte identifikátor URI pack:z identifikátoru URI balíčku a části identifikátoru URI pomocí PackUriHelper.
  2. Získejte datový proud bitů voláním PackWebRequest.
  3. Načtěte obsah části a parsujte, abyste získali relativní odkazy.
  4. Přeložte tyto relativní odkazy na identifikátor URI základní části (identifikátor URI pack:) složený v kroku 1).
  5. K překladu relativních odkazů použijte System.Uri a k získání uvedených prostředků použijte PackWebRequest .

Vytvoření identifikátoru URI pack:pro požadovaný balíček

Identifikátor URI balíčku "pack:" lze vytvořit pomocí metody PackUriHelper.Create .

Příklad: PackUriHelper.Create

//Given the URI for a package
Uri packageUri = new Uri("http://www.newsdocs.com
               /local/today.container");

//Use the Create method to create a "pack:" URI from a non-"pack:" URI
Uri packUri = PackUriHelper.Create(packageUri);

//The resulting packUri value is
//"pack://http%3a,,www.newsdocs.com,local,today.container/"

Vytvořený identifikátor URI pack:" se předá packWebRequest , aby bylo možné získat prostředek balíčku.

Vytvoření identifikátoru URI pack:pro požadovanou část

Identifikátor URI "pack:" části lze vytvořit pomocí metody PackUriHelper.Create .

Příklad: PackUriHelper.Create

//Given the URI for package 
Uri packageUri = new Uri("http://www.newsdocs.com
               /local/today.container");

//Given the URI for a part
Uri partUri = new Uri("/sports.xml", UriKind.Relative);

//Use the PackUriHelper.Create method to create a "pack:" URI

Uri packUri = PackUriHelper.Create (packageUri, partUri);

//The resulting packUri value is
//"pack://http%3a,,www.newsdocs.com,local,today.container/sports.xml"

Vytvořený identifikátor URI pack:" se předá packWebRequest , aby bylo možné získat prostředek součásti.

Řešení relativních odkazů

Při zpracování obsahu části mohou být nalezeny relativní odkazy, které odkazují na jiné části nebo prostředky. Vyřešení těchto odkazů je prvním krokem při získání odkazovaných prostředků.

Relativní odkaz v obsahu části se přeloží na základní identifikátor URI části na identifikátor URI "pack:" cílové části. Identifikátor URI "pack:" cílové části se předá PackWebRequest , aby bylo možné získat prostředek součásti z balíčku. Název cílové části, odvozený od "pack:" identifikátoru URI cílové části, lze také použít k získání cílové části předáním názvu části Package.GetPart metoda.

Při překladu relativních odkazů na cílové části existuje několik cest, kterými se řešení může ubírat v závislosti na tom, jaké informace jsou k dispozici na začátku a jestli je balíček otevřený (nebo se dá otevřít). Dvě z těchto cest jsou následující:

  • Na začátku:

    1. Identifikátor URI "pack:" části obsahující odkaz je známý.
    2. Balíček není otevřený.
    //Given the "pack:" URI for the part "/files/fixeddoc.xaml"
    //packUri =
    // "pack://http%3a,,www.newsdocs.com,local,today.container
    // /files/fixeddoc.xaml"
    
    //The part "/files/fixeddoc.xaml" contains 
    //the relative reference "../images/1.jpg"
    
    Uri relativeReference = new Uri("../images/1.jpg", 
                      UriKind.Relative);
    
    //Use System.Uri to directly obtain the absolute target URI
    
    Uri targetPackUri = new Uri(packUri, relativeReference);
    
    //The value of the resulting targetPackUri is 
    //"pack://http%3a,,www.newsdocs.com,local,today.container
    // /images/1.jpg"
    
    //Now another PackWebRequest can be made using 
    //this targetPackUri value.
    
  • Na začátku:

    1. Název části obsahující odkaz je známý.
    2. Balíček je otevřený.
    //Given "package" as the current instance of the Package class.
    //Given the relative reference = "../../images/1.jpg"
    
    Uri relativeReference = new Uri("../../images/1.jpg", 
                      UriKind.Relative);
    
    //Given the URI of the part that contains the relative reference
    
    Uri partUri = new Uri("/files/fixeddoc.xaml");
    
    //Use PackUriHelper.ResolvePartUri to obtain the resolved part URI 
    //of the target based on the part URI above and the relative 
    //reference in that part
    
    Uri targetPartUri = PackUriHelper.ResolvePartUri
                   (partUri, relativeReference);
    
    //The resulting targetPartUri value is "fixeddoc.xaml"
    //Now use the package.GetPart method to obtain the target part
    
    PackagePart packagePart = package.GetPart(targetPartUri);
    

Zadání názvů částí do třídy balíčku

Jakmile je balíček otevřený, třída Package je užitečná pro přidávání částí do balíčků, získávání částí a odstraňování částí. Metody třídy Package , například Package.AddPart, Package.DeletePart a Package.GetPart, přebírají identifikátor URI části jako parametr. Metoda PackUriHelper.CreatePartUri lze použít k vytvoření platného názvu součásti z odkazu, který je relativní k základnímu identifikátoru URI balíčku.

Příklad: PackUriHelper.CreatePartUri

//Given a URI

Uri partUri = PackUriHelper.CreatePartUri 
            (new Uri "files/a.xaml",UriKind.Relative))

//The URI will be checked for validity, and a leading slash
//will be added. The resulting partUri value is "/files/a.xaml"

Služba pro generování relativních odkazů

Aplikace pro vytváření může potřebovat odvodit relativní odkaz, který po umístění do obsahu zdrojové části odkazuje na cílovou část. K tomuto účelu slouží metoda GetRelativeUri .

Příklad: GetRelativeUri – příklad

//Given the URI of the source part

Uri sourcePartUri = new Uri("/tiles/pages/a.xaml", UriKind.Relative);

//Given the URI of the target part

Uri targetPartUri = new Uri("/images/event1/1.jpg", UriKind.Relative);

//Use PackUriHelper.GetRelativeUri to generate the relative reference
//that will be placed in the content of the source part.

Uri relativeReference = PackUriHelper.GetRelativeUri
               (sourcePartUri, targetPartUri);

//The resulting relativeReference value is "../../images/event1/1.jpg"

Získání prostředků balíčku pomocí rutiny PackWebRequest

Aplikace mohou získat balíčky a části prostředků pomocí PackWebRequest, třídy odvozené z System.Net.WebRequest. PackWebRequest vrátí prostředek adresovaný daným identifikátorem URI pack:.

Obecně platí, že inicializování PackWebRequest pro identifikátor URI pack:" se skládá z následujících kroků:

  1. Je zaškrtnutá gramatika identifikátoru URI pack:.
  2. Komponenta autority se extrahuje z identifikátoru URI "pack:" a zkontroluje se, jestli odpovídá gramatice absolutního identifikátoru URI.
  3. Pokud je komponenta path identifikátoru URI pack:" prázdná:
  • Datový proud balíčku se získá pro komponentu autority a vrátí se volajícímu.

    V opačném případě, pokud komponenta cesty není prázdná:

    1. Otevřený balíček se získá pro prostředek identifikovaný komponentou autority. V závislosti na sadě CachePolicyPackWebRequest buď získá otevřený balíček z PackageStore, nebo vytvoří vnitřní WebRequest pro prostředek balíčku a otevře balíček z vráceného datového proudu balíčku.
    2. Část se získá pomocí komponenty path identifikátoru URI pack:.
    3. Datový proud části se získá a vrátí volajícímu.

PackWebResponse.GetStream vrátí datový proud bitů představujících buď celý balíček ( datový proud balíčku), nebo jednu část v balíčku ( část streamu).

Na rozdíl od většiny streamů WebResponse je datový proud balíčku vyhledatelný pomocí streamu Stream.Seek. Datový proud balíčku lze použít k vytvoření objektu balíčku.

Při práci s prostředkem balíčku přes protokol http:, PackWebRequest podporuje progresivní načítání částí: tj. schopnost získat prostředky částí v libovolném pořadí, aniž by se načítala všechna data v balíčku až do části dat.

PackWebRequest poskytuje pouze zařízení pro spotřebu prostředků. Nelze ho použít k publikování nebo odeslání dat na server.

PackWebRequest v současné době nepodporuje asynchronní operace (například BeginGetResponse) ani PackWebRequest nepodporuje vnořené balíčky (popsané výše v části v rámci balíčku).

The PackageStore

Při načítání balíčků, které obsahují části obsahující mnoho odkazů na jiné části, je možné zlepšit dobu odezvy požadavků na prostředky a snížit síťový provoz pomocí packageStore. PackageStore je místní slovník odkazů na otevřené balíčky. Každý balíček zaregistrovaný v PackageStore je identifikován hodnotou identifikátoru URI klíče.

PackageStore umožňuje příkazu PackWebRequest získat prostředky podle potřeby z balíčku, aniž by pokaždé, když je z balíčku potřeba jiný prostředek, vyžadoval server požadavek.

PackageStore se automaticky nezmění v důsledku volání PackWebRequest – musí se explicitně upravit. Existují dvě veřejné metody, které slouží k přidání nebo odebrání odkazů na otevřené balíčky v PackageStore: Package.AddPackage a Package.RemovePackage.

Výchozí zásady mezipaměti (CacheIfAvailable) nastavené na PackWebRequest způsobí, že se třída pokusí použít PackageStore k získání balíčku. PackWebRequest je možné při získávání prostředků vynutit, aby ignoroval obsah packageStore nastavením zásad mezipaměti na BypassCache, jak je popsáno v další části Zásady mezipaměti.

Při získávání bitů balíčku nebo části podle výchozích zásad mezipaměti PackWebRequest nejprve zkontroluje PackageStore , zda je balíček zaregistrovaný s klíčem, který se rovná komponentě autority identifikátoru URI pack:. Pokud PackageStore neobsahuje balíček pro klíč, PackWebRequest vytvoří vnitřní WebRequest ke stažení prostředku pomocí komponenty autority identifikátoru URI pack:.

Zásady mezipaměti

Zásady mezipaměti definují pravidla, která se používají k určení, jestli je možné vyplnit žádost o prostředek pomocí kopie prostředku uložené v mezipaměti.

Při použití PackWebRequest existují dvě úrovně zásad mezipaměti, které je možné explicitně nastavit. Zásady mezipaměti lze nastavit pro samotný PackWebRequest , které řídí interakci s PackageStore. Zásady mezipaměti je také možné nastavit pro mezipaměť řízenou vnitřní webrequest. K vnitřnímu požadavku WebRequest může přistupovat PackWebRequest pomocí PackWebRequest.GetInternalRequest().

Zásady mezipaměti nastavené na vnitřní WebRequest nebudou mít žádný vliv, pokud packWebRequest.CachePolicy je nastaven na CacheOnly, což způsobí, že prostředek balíčku bude získán z PackageStore.

PackWebRequest.CachePolicy podporuje podmnožinu zásad, jak je uvedeno níže, kvůli specifickým možnostem PackageStore.

Tabulka 1. Zásady PackWebRequest.CachePolicy

Cachepolicy Description
BypassCache Ignorujte položky PackageStore s odpovídajícím identifikátorem URI.
CacheOnly Zvažte pouze položky PackageStore (nikdy nevytvovávejte WebRequest pro dotazování serveru na data).
CacheIfAvailable Zkontrolujte PackageStore a použijte libovolný balíček, pokud je nalezen; v opačném případě proveďte síťový požadavek na prostředek označený identifikátorem URI balíčku (vnitřní identifikátor URI balíčku:). Tato možnost je výchozí.

Pro PackWebRequest, nastavení všech ostatních CachePolicy hodnoty výsledkem WebException.

Progresivní načítání

PackWebRequest může postupně načíst část balíčku při přístupu k balíčku přes protokol http:. Progresivní načítání umožňuje aplikacím získat přístup k částečným prostředkům předtím, než bude celý balíček místně dostupný. Funkce progresivního načítání PackWebRequest je automatická: volající aplikace má vyšší výkon bez zásahu.

Progresivní načítání je založené na vytváření "požadavků na rozsah bajtů" pro prostředky, jak je definováno v protokolu http:1.1. Formát souboru ZIP, který se používá k ukládání balíčků ve fyzické podobě, těží z tohoto mechanismu, protože archivní formát ZIP uchovává důležité informace v "centrálním adresáři" na fyzickém konci souboru.

Po vyžádání celého balíčku pomocí PackWebRequest začne služba vracet datový proud, ve kterém může volající hledat. Při otevření balíčku ve streamu poskytovaném PackWebRequest může volající získat části rychleji než při provádění přímých požadavků pomocí například protokolu http:.

Služby pro vyhodnocování a rozklad identifikátorů URI

Identifikace názvů částí relací vrácených třídou balíčku

Při správě kolekce částí, které byly získány pomocí Package.GetParts metoda, mohou být části relace identifikovány, aby je bylo možné zpracovat odděleně od ostatních částí. PackUriHelper.IsRelationshipPartUri se používá k identifikaci, zda je část součástí relace.

Příklad: PackUriHelper.IsRelationshipPartUri

//Given the URI for a part

Uri partUri = new Uri("/_rels/sports.rels", UriKind.Relative);

bool isRelationshipPart = PackUriHelper.IsRelationshipPartUri(PartUri);

//The resulting isRelationshipPart value is "TRUE"

Pro práci s názvy částí relace jsou k dispozici dvě další metody PackUriHelper . PackUriHelper.GetRelationshipPartUri vrátí název části relace s názvem zdrojové části. PackUriHelper.GetSourcePartUriFromRelationshipPartUri vrátí název zdrojové části pro daný název části relace.

Porovnání identifikátorů URI pro ekvivalenci

Aplikace, která používá mezipaměť pro ukládání součástí při vytváření nebo používání balíčku, může potřebovat provést kontroly ekvivalentních názvů součástí. Metoda PackUriHelper.ComparePartUri kontroluje ekvivalenci názvů součástí.

Příklad: PackUriHelper.ComparePartUri

//Given two part names in the same package
//firstPartName = "/a.xaml"
//secondPartName = "/A.xaml"

//Use PackUriHelper.ComparePartUri to identify if the names 
//are equivalent.

Bool isSamePartName = PackUriHelper.ComparePartUri 
               (firstPartName, secondPartName);

//The resulting isSamePartName value is "TRUE"

Chcete-li zjistit lexikální ekvivalent dvou identifikátorů URI pack:, použijte metodu PackUriHelper.ComparePackUri .

Příklad: PackUriHelper.ComparePackUri

//Given two "pack:" URIs
//firstPackUri =
// "PACK://HTTP%3A,,WWW.NEWSDOCS.COM,local,today.container
// /FILES/FIXEDDOC.XAML"
//secondPackUri = 
// "pack://http%3a,,www.newsdocs.com,local,today.container
// /files/fixeddoc.xaml"

//Use PackUriHelper.ComparePackUri to identify if the same resource 
//is targeted.

bool isSameResource = PackUriHelper.ComparePackUri 
            (firstPackUri, secondPackUri);

//The resulting isSameResource value is "TRUE"

Extrahování identifikátorů URI komponent z identifikátoru URI pack:.

Chcete-li extrahovat identifikátor URI balíčku komponent a část identifikátoru URI z identifikátoru URI pack:, použijte metody PackUriHelper.GetPackageUri a PackUriHelper.GetPartUri v uvedeném pořadí.

Příklad: PackUriHelper.GetPackageUri

//Given the "pack:" URI for a package

Uri packUri = "pack://http%3a,,www.newsdocs.com,local,today.container
            /files/abc.xaml";

//Use PackUriHelper.GetPackageUri to obtain the URI of the package

Uri packageUri = new PackUriHelper.GetPackageUri(packUri);

//The resulting packageUri value is
//"http://www.newsdocs.com/local/today.container"

Příklad: GetPartUri – příklad

//Given the "pack:" URI for a part

Uri packUri = "pack://http%3a,,www.newsdocs.com,local,today.container
         /files/abc.xaml";

//Use PackUriHelper.GetPartUri to obtain the URI of the part

Uri partUri = new PackUriHelper.GetPartUri(packUri);

//The resulting partUri value is "/files/abc.xaml"

Reference

Otevřené konvence balení

Identifikátor URI (Uniform Resource Identifier): Obecná syntaxe

Specifikace dokumentu Open XML

Identifikátory iri (Internationalized Resource Identifier)