Open Packaging Conventions의 주소 지정 모델

 

데이비드 멜처와 안드레이 서
Microsoft Corporation

2006년 6월

적용 대상:
   Open Packaging Conventions
   Microsoft Office 2007
   Microsoft Windows Vista
   Microsoft .NET Framework

요약: 이 문서에서는 패키지 및 해당 파트의 주소 지정 방법, 패키지 파트의 상대 참조를 확인하는 방법, 애플리케이션이 .NET Framework 및 클래스의 도움을 받아 패키지 주소 지정 모델을 사용하는 방법을 포함하여 Open Packaging Conventions에서 사용되는 주소 지정 모델에 대한 개요를 제공합니다. (인쇄된 페이지 16개)

콘텐츠

서문
주소 지정 모델
"pack:" URI에 대한 프로그래밍 지원
참조

서문

Office 2007 및 Windows Vista 디자인의 일환으로 Microsoft는 오픈 패키징 규칙을 도입했습니다. 이러한 규칙은 콘텐츠를 "패키지"로 구성하는 방법을 설명합니다. 콘텐츠의 몇 가지 예로는 문서, 미디어 컬렉션 및 애플리케이션 라이브러리가 있습니다. 패키지는 콘텐츠의 모든 구성 요소를 단일 개체로 집계합니다.

예를 들어 워드 프로세싱 애플리케이션은 패키지를 사용하여 문서의 페이지, 필요한 글꼴 및 이미지, 차트 및 주석을 페이지에 저장할 수 있습니다. 문서 보기 또는 관리 애플리케이션은 패키지에 있는 콘텐츠의 일부만 표시할 수 있습니다. 애플리케이션은 XPS(XML Paper Specification)와 같은 패키지 기반 형식을 사용하여 고정 레이아웃 콘텐츠 및 리소스를 프린터로 보낼 수 있습니다.

이 문서에서는 패키지 및 해당 파트의 주소 지정 방법 및 패키지 파트의 상대 참조를 확인하는 방법을 포함하여 Open Packaging Conventions에서 사용되는 주소 지정 모델에 대한 개요를 제공합니다. 이 문서에서는 애플리케이션이 .NET Framework 및 .NET Framework 3.0 클래스의 도움으로 패키지 주소 지정 모델을 사용하는 방법에 대해서도 설명합니다. 이 문서는 주로 패키지를 처리, 생성 또는 사용할 애플리케이션 개발자를 위해 작성되었습니다.

패키지 주소 지정 모델을 구현하는 데 필요한 전체 규범 정보는 Open Packaging Conventions 사양을 참조하세요. .NET Framework 3.0 및 .NET SDK는 설명된 클래스 및 메서드에 대한 자세한 정보를 제공합니다.

이 개요에 제시된 자료는 URI 사양에 대한 기본 지식을 가정합니다. RFC 3986에 따라 사용되는 용어는 URI, URI 참조, 체계 구성 요소, 기관 구성 요소, 경로 구성 요소, 경로 절대상대 참조입니다. URI라는 용어는 항상 URI의 절대 형식을 나타냅니다. 즉, 체계 구성 요소가 있고 다른 모든 구성 요소가 스키마별 문법과 일치합니다. 여기서 사용되는 주소 지정 가능 용어는 리소스를 식별하는 URI가 있음을 나타냅니다.

주소 지정 모델

Open Packaging Conventions는 패키지의 콘텐츠 및 리소스를 구성하기 위한 논리 모델을 정의하고 ZIP, XML 및 기타 공개적으로 사용 가능한 기술을 기반으로 이 논리 모델에서 실제 표현으로 매핑을 제공합니다.

Open Packaging Conventions에서 설명하는 논리적 패키징 모델은 파트 컬렉션을 보유하는 패키지 추상화 를 정의합니다. 파트는 서로 관계를 가질 수 있으며 패키지는 파트와 관계를 가질 수 있습니다. 패키징 모델은 패키지의 파트를 명명, 참조 및 관련하는 방법을 지정합니다. 규칙에 의해 정의된 주소 지정 모델은 패키지에서 파트 리소스를 참조하고 가져올 수 있는 기반입니다.

주소 지정 가능한 패키지 리소스

패키지 instance 전체는 패키지 instance 각 파트와 마찬가지로 주소 지정이 가능한 리소스입니다.

패키지 주소를 단위로 지정

애플리케이션은 모든 스키마(예: "http:", "ftp:" 등)가 있는 URI를 사용하여 패키지를 단위로 처리하여 전체 패키지로 구성된 비트 스트림을 가져올 수 있습니다.

애플리케이션은 Open Packaging Conventions에 정의된 "pack:" URI 체계를 사용하여 패키지를 처리할 수도 있습니다. 이 체계는 패키지를 식별하는 전체 URI가 인코딩된 형식의 "pack:" URI의 기관 구성 요소에 보관되도록 지정합니다.

예제: 패키지 주소 지정

패키지 리소스는 다음 예제에서 각각 "http:" 및 "pack:" URI로 처리됩니다.

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

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

획득한 패키지 리소스의 MIME 형식은 패키지의 파일 형식을 나타냅니다. 예를 들어 XPS 문서 형식(.xps), Office Open XML 형식(.docx) 또는 Open Packaging Conventions를 준수하는 다른 형식일 수 있습니다.

애플리케이션은 다양한 이유(예: 성능 향상)를 위해 도메인과 관련된 URI를 "pack:" URI의 기관 구성 요소로 사용할 수 있습니다. 이러한 URI는 지정된 애플리케이션의 컨텍스트에서만 확인할 수 있습니다. 이러한 애플리케이션별 URI에 사용되는 프로그래밍 기술은 나중에 "PackageStore"에서 설명합니다.

패키지 내의 파트 주소 지정

패키지의 파트는 "pack:" URI를 사용하여 주소가 지정됩니다. 파트를 주소 지정하는 "pack:" URI의 구조는 다음과 같습니다. pack://< 자유><경로>

예: 주소 지정 부분

pack://http%3a,,www.site.com,windows,p1.xps/fonts/arial.ttf는 에 의해 http://www.site.com/windows/p1.xps주소가 지정된 패키지에서 /fonts/arial.ttf라는 파트의 주소를 지정합니다.

기관 구성 요소는 전체 패키지의 인코딩된 URI를 보유합니다. 경로 구성 요소는 해당 패키지에 있는 파트의 이름을 보유합니다. 파트 이름은 경로 절대 URI 구성 요소([2], 섹션 3.3)에 대해 정의된 문법을 준수하며 몇 가지 추가 제한 사항([1], 섹션 2.1.1.1)이 있습니다.

예: 파트 이름

/documents/doc1.xaml

/pages/page4.xaml

/fonts/arial.ttf

파트 이름은 대/소문자를 구분하지 않는 ASCII 문자열입니다. 패키지의 모든 파트에는 고유한 이름이 있습니다.

조각 식별자를 사용하여 파트 참조

Open Packaging Conventions를 사용하는 일부 애플리케이션은 형식별 조각 식별자가 있는 패키지 단위의 비"pack:" URI를 사용하여 파트를 참조할 수 있습니다.

예: 비"pack:" URI를 사용하여 파트 참조

URI http://www.site.com/windows/p1.xps\#15 는 p1.xps 문서의 페이지 15를 나타내는 부분을 참조하는 데 사용됩니다([3], 섹션 9.2.2 및 9.2.3).

유효하고 특정 시나리오에서는 비"pack:" URI가 파트를 참조하는 데 유용하지만 이러한 URI를 기본 URI로 사용하여 파트 콘텐츠의 상대 참조를 resolve 수 없습니다.

파트 내의 항목 참조

파트는 패키지 내에서 가장 세분화된 주소 지정 가능한 리소스입니다. 그러나 애플리케이션은 파트의 콘텐츠 내에서 항목을 참조해야 할 수 있습니다. 특정 콘텐츠 형식의 경우 조각 식별자([2], 섹션 3.5)를 통해 항목을 참조할 수 있습니다. 개방형 패키징 규칙은 조각 식별자를 지정하지 않습니다. 조각 식별자를 사용하는 애플리케이션은 이를 제대로 처리해야 합니다.

예: 파트 내 항목 참조

pack://http%3a,,www.site.com,windows,p1.xps/pages/page1.xaml#//[@Id="A012"]/pages/page1.xaml이라는 파트의 콘텐츠 내에서 ID 특성 값이 A012인 XML 노드 집합을 나타냅니다.

중첩된 패키지

패키지를 중첩할 수 있습니다. 패키지의 파트는 전체 패키지를 포함하여 모든 형식의 콘텐츠를 보유할 수 있습니다. 중첩된 패키지의 부분은 이 중첩된 패키지([1], 부록 D.3)를 보유하는 부분을 나타내는 기관 구성 요소를 사용하여 "pack:" URI로 처리할 수 있습니다.

예: 중첩된 패키지의 요소 주소 지정

http://www.site.com/package 있는 패키지에는 /nested-package라는 파트가 포함되어 있습니다.

,

"pack:" URI pack://http%3a,,www.site.com,package/nested-package로 주소를 지정합니다.

앞의 URI로 주소가 지정된 파트에는 /p1.xaml이라는 파트가 포함된 패키지 단위가 포함되어 있습니다.

중첩된 패키지에 있는 이 부분의 주소는 다음과 같습니다.

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

파트 콘텐츠의 참조

XML과 같은 특정 형식의 콘텐츠가 있는 파트에는 URI 참조가 포함될 수 있습니다. URI 참조는 URI 또는 상대 참조일 수 있습니다. URI 참조는 유니코드 문자열로 콘텐츠에 표시될 수 있습니다. 이러한 URI 참조를 확인하는 애플리케이션은 문자열을 URI 형식([4], 섹션 3.1)으로 변환해야 합니다.

상대 참조는 참조를 포함하는 콘텐츠의 기본 URI를 기준으로 표현되는 URI입니다. 파트 콘텐츠의 기본 기본 URI는 파트를 주소 지정하는 "pack:" URI입니다.

예: 기본 URI

주소가 지정된 http://www.site.com/windows/p1.xps 패키지의 /pages/page1.xaml이라는 파트에 대한 기본 URI는 다음과 같습니다.

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

파트 콘텐츠의 항목에서 상대 참조를 resolve 위해 대체 기본 URI가 필요한 경우 애플리케이션은 대체 항목을 명시적으로 지정해야 합니다. 특정 콘텐츠 형식은 대체 기본 URI를 지정하는 특정 방법을 노출합니다. 예를 들어 XML은 xml:base 특성을 사용하고, HTML은 기본> 요소를 사용하고<, Open Packaging Conventions는 Relationship 요소에 TargetMode 특성을 사용합니다.

상대 참조에 대한 기본 URI로 파트의 "pack:" URI를 사용하면 상대 참조가 거의 사용되지 않는 한(즉, "//"로 시작하는 상대 참조) 상대 참조가 동일한 패키지([2], 섹션 5.2)에 속하게 됩니다.

예: 상대 참조 확인

상대 참조입니다. /.. pack://http%3a,,www.site.com,windows,p1.xps/pages/page1.xaml로 주소가 지정된 부분 내의 /page2.xaml은 pack://http%3a,,www.site.com,windows,p1.xps/page2.xaml로 확인되어 /page2.xaml이라는 파트의 주소를 지정합니다.

패키지 생산자는 부품 이름을 유효한 형식의 상대 참조로 사용할 수 있습니다. 그러나 파트 이름을 상대 참조로 사용하는 경우 생산자는 참조된 파트를 패키지 외부에서 추출된 리소스로 처리할 수 있는지 여부를 고려해야 합니다. 패키지에서 파트를 추출한 후에는 상대 참조로 사용되는 부품 이름이 예상대로 확인되지 않을 수 있습니다. 파트 이름 문법으로 지정된 파트 이름에 대한 필수 선행 슬래시는 이러한 상대 참조가 현재 권한의 루트에서 확인됨을 의미합니다.

예: 추출된 리소스 주소 지정

/doc1/pages/page1.xaml이라는 파트의 콘텐츠에서 상대 참조 /page2.xaml은 /page2.xaml이라는 파트의 주소를 지정하고 상대 참조 ./page3.xaml/doc1/pages/page3.xaml이라는 파트의 주소를 지정합니다.

/doc1/pages/page1.xaml, /doc1/pages/page3.xaml/part2.xaml이 패키지에서 file:///c:/mydocs/doc1/pages/page1.xaml, file:///c:/mydocs/doc1/pages/page3.xamlfile:///c:/mydocs/page2.xaml 파일로 추출된 후 상대 참조 ./page3.xaml은 파일 file:///c:/mydocs/doc1/pages/page3.xaml 처리합니다. 그러나 상대 참조 /page2.xaml은 이제 file:///page2.xaml 파일의 주소를 지정합니다.

관계의 상대 참조

패키지 열기 규칙은 패키지의 원본 파트와 대상 부분 간의 연결을 관계 로 정의합니다([1], 섹션 1.3).

관계는 원본에 따라 그룹화되고 저장됩니다. 관계 파트는 동일한 원본 부분에서 시작되는 관계를 보유합니다. 각 관계는 이 관계 부분의 내용 내에서 XML 요소에 의해 설명됩니다. 관계 부분은 관계 부분에 대해 정의된 명명 규칙을 사용하여 이 원본 부분과 고유하게 연결됩니다(그 반대의 경우도 마찬가지).

각 Relationship 요소에 지정된 URI의 기본 기본 URI는 원본 부분([1], 섹션 1.3.5)의 "pack:" URI입니다. Relationship 요소의 TargetMode 특성은 지정된 관계의 기본 URI를 나타냅니다.

예: Relationship 요소

/pages/page1.xaml이라는 원본 파트에서 동일한 패키지 내의 대상 부분 /fonts/arial.ttf까지의 관계를 정의하는 관계 파트의 요소는 다음과 같을 수 있습니다.

<관계 형식="https://schemas.microsoft.com/xps/2005/06/restricted-font"

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

TargetMode 특성의 내부 값은 Relationship 요소의 기본 URI가 관계 파트 콘텐츠의 기본값이며 관계 원본 파트의 "pack:" URI와 동일하다는 것을 나타냅니다. 앞의 예제에서 Relationship 요소의 기본 URI는 /pages/page1.xaml 부분의 "pack:" URI입니다.

관계는 전체 패키지의 위치를 기준으로 외부 리소스를 대상으로 할 수도 있습니다.

예: 외부 대상과의 관계

file:///c:/office12/sample.docx에 있는 패키지의 경우 XML 요소

<관계 ID="rId9"

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

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

file:///c:/office12/icon.jpg파일을 대상으로 하는 관계를 정의합니다.

TargetMode 특성의 외부 값은 관계가 패키지 외부의 리소스를 대상으로 지정해야 한다고 지정합니다. Target 특성에 상대 참조가 있는 경우 기본 URI가 필요합니다. 이 관계 요소의 기본 URI는 전체 패키지의 URI여야 합니다.

관계에 대한 참조 위임

일부 패키지 기반 형식은 콘텐츠에서 URI 참조를 사용하지 않고 관계에 대한 참조를 위임하지 않을 수 있습니다. 이 위임 기술은 각 Relationship 요소에서 고유 ID 값을 사용하여 파트 콘텐츠의 상대 참조를 해당 관계에 매핑하는 방법을 기반으로 합니다.

예: 파트 콘텐츠의 상대 참조를 관계에 매핑

file:///c:/office12/sample.docx 있는 패키지에는 /word/document.xml 라는 부분이 있습니다.

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

이 파트에 연결된 관계 부분은 요소를 보유합니다.

<관계 ID="rId6"

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

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

/ word/media/image1.jpeg라는 파트에 요소를 연결합니다.

이 방법의 이점은 애플리케이션이 파트의 콘텐츠를 보지 않고 패키지 내의 모든 참조를 식별하고 유지 관리할 수 있다는 것입니다.

그러나 참조가 관계에 위임된 경우 느슨한 파일로 추출된 패키지 파트가 제대로 작동하지 않을 수 있습니다. 추출 후 관계 대상이 작동하려면 소비 애플리케이션에는 관계에 대한 특별한 지식, 관계 부분 이름 지정을 위한 Open Packaging Conventions 및 관계 파일에 대한 기본 URI 정의가 필요합니다.

"pack:" URI에 대한 프로그래밍 지원

패키지를 생성 및/또는 사용하는 애플리케이션은 패키지 및 파트 주소와 함께 작동하며 파트 콘텐츠 내에서 상대 참조를 resolve. microsoft에서 제공하는 차세대 관리 API 집합을 제공하는 .NET Framework 3.0에는 Open Packaging Conventions의 주소 지정 모델을 지원하는 클래스가 포함되어 있습니다. 이러한 클래스를 사용하면 애플리케이션이 참조를 작성 및 구문 분석하고 패키지 리소스를 가져올 수 있습니다. PackUriHelper 클래스는 "pack:" URI의 처리를 용이하게 하는 데 사용됩니다. PackWebRequest 클래스는 "pack:" URI를 사용하여 주소가 지정된 리소스를 가져오는 데 사용됩니다.

이 섹션에서는 이러한 서비스가 참조 작성, 구문 분석 및 확인에서 수행하는 함수를 보여 줍니다.

패키지 서비스를 사용할 수 있도록 설정

패키징 서비스 클래스를 사용하려면 .NET Framework 버전 3.0 이상을 설치해야 합니다. 클래스는 System.IO.Packaging 네임스페이스에서 찾을 수 있습니다.

"pack:" URI가 관련된 작업에 System.Uri 를 사용하기 전에 애플리케이션 도메인에 대해 "pack:" URI 체계를 등록해야 합니다. "pack:" URI 체계를 등록하는 가장 쉬운 방법은 PackUriHelper 클래스의 메서드를 호출하는 것입니다. 다음 예제와 같이 UriParser.Register 메서드를 사용하여 도우미 클래스를 호출하지 않고 스키마를 등록할 수도 있습니다. 그러나 이 방법을 사용하려면 보안 권한이 필요합니다.

예: "pack:" URI 체계 등록

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

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

대상 리소스의 "pack:" URI 가져오기

패키지를 사용할 때 전체 패키지 또는 한 번에 하나의 파트를 개체로 가져올 수 있습니다. 두 경우 모두 PackUriHelper.Create 메서드를 사용하여 패키지 또는 파트 리소스의 "pack:" URI를 만들 수 있습니다. 이 "pack:" URI는 리소스를 가져오기 위해 PackWebRequest 메서드에 전달됩니다. PackWebRequest 는 다음 섹션인 "PackWebRequest를 사용하여 패키지 리소스 가져오기"에서 자세히 설명합니다.

PackUriHelperPackWebRequest 클래스를 사용하여 패키지 사용을 지원하는 방법에 대한 일반적인 예제는 다음 단계에 자세히 설명되어 있습니다. 패키지 URI 및 파트 URI가 알려진 경우 애플리케이션은 다음을 수행할 수 있습니다.

  1. PackUriHelper를 사용하여 패키지 URI 및 파트 URI에서 "pack:" URI를 작성합니다.
  2. PackWebRequest를 호출하여 비트 스트림을 가져옵니다.
  3. 파트의 콘텐츠를 로드하고 구문 분석하여 상대 참조를 가져옵니다.
  4. 파트 기본 URI(1단계에서 구성된 "pack:" URI)에 대한 이러한 상대 참조를 해결합니다.
  5. System.Uri를 사용하여 상대 참조를 resolve PackWebRequest를 사용하여 표시된 리소스를 가져옵니다.

원하는 패키지에 대한 "pack:" URI 만들기

PackUriHelper.Create 메서드를 사용하여 패키지의 "pack:" URI를 만들 수 있습니다.

예: 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/"

생성된 "pack:" URI는 패키지 리소스를 가져오기 위해 PackWebRequest 에 전달됩니다.

원하는 파트에 대한 "pack:" URI 만들기

PackUriHelper.Create 메서드를 사용하여 파트의 "pack:" URI를 만들 수 있습니다.

예: 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"

만든 "pack:" URI는 파트 리소스를 얻기 위해 PackWebRequest 에 전달됩니다.

상대 참조 확인

파트의 콘텐츠를 처리할 때 다른 파트 또는 리소스를 참조하는 상대 참조를 찾을 수 있습니다. 이러한 참조를 확인하는 것은 참조된 리소스를 가져오는 첫 번째 단계입니다.

파트 콘텐츠의 상대 참조는 대상 파트의 "pack:" URI에 대한 파트의 기본 URI에 대해 확인됩니다. 대상 파트의 "pack:" URI는 패키지에서 파트 리소스를 가져오기 위해 PackWebRequest 에 전달됩니다. 대상 파트의 "pack:" URI에서 파생된 대상 파트의 이름을 사용하여 파트 이름을 Package.GetPart 메서드에 전달하여 대상 파트를 가져올 수도 있습니다.

대상 파트에 대한 상대 참조를 확인할 때 시작 시 사용할 수 있는 정보 및 패키지가 열려 있는지 또는 열 수 있는지에 따라 해결에 사용할 수 있는 몇 가지 경로가 있습니다. 이러한 경로 중 두 가지는 다음과 같습니다.

  • 시작 시:

    1. 참조를 포함하는 부분의 "pack:" URI를 알 수 있습니다.
    2. 패키지가 열려 있지 않습니다.
    //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.
    
  • 시작 시:

    1. 참조를 포함하는 파트의 이름을 알 수 있습니다.
    2. 패키지가 열려 있습니다.
    //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);
    

패키지 클래스에 부품 이름 제공

패키지가 열리면 Package 클래스는 패키지에 파트를 추가하고, 파트를 가져오고, 파트를 삭제하는 데 유용합니다. Package.AddPart, Package.DeletePartPackage.GetPart와 같은 Package 클래스의 메서드는 URI 부분을 매개 변수로 사용합니다. PackUriHelper.CreatePartUri 메서드를 사용하여 패키지의 기본 URI를 기준으로 하는 참조에서 유효한 부품 이름을 만들 수 있습니다.

예: 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"

상대 참조를 생성하기 위한 서비스

제작 애플리케이션은 원본 파트의 콘텐츠에 배치될 때 대상 부분을 가리키는 상대 참조를 파생해야 할 수 있습니다. GetRelativeUri 메서드는 이 용도로 사용됩니다.

예: GetRelativeUri 예제

//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"

PackWebRequest를 사용하여 패키지 리소스 가져오기

애플리케이션은 System.Net.WebRequest에서 파생된 클래스인 PackWebRequest를 사용하여 패키지 및 파트 리소스를 가져올 수 있습니다. PackWebRequest 는 지정된 "pack:" URI로 주소가 지정된 리소스를 반환합니다.

일반적으로 "pack:" URI에 대한 PackWebRequest 시작은 다음 단계로 구성됩니다.

  1. "pack:" URI 문법이 선택되어 있습니다.
  2. 권한 구성 요소는 "pack:" URI에서 추출되고 절대 URI에 대한 문법을 따르는지 여부를 확인합니다.
  3. "pack:" URI의 경로 구성 요소가 비어 있는 경우:
  • 패키지 스트림은 기관 구성 요소에 대해 가져오고 호출자에게 반환됩니다.

    그렇지 않으면 경로 구성 요소가 비어 있지 않으면 다음을 수행합니다.

    1. 권한 구성 요소로 식별된 리소스에 대해 열린 패키지를 가져옵니다. CachePolicy 집합에 따라 PackWebRequestPackageStore에서 열린 패키지를 가져오거나 패키지 리소스에 대한 내부 WebRequest를 만들고 반환된 패키지 스트림에서 패키지를 엽니다.
    2. 파트는 "pack:" URI의 경로 구성 요소를 파트 이름으로 사용하여 가져옵니다.
    3. 파트 스트림을 가져와서 호출자에게 반환합니다.

PackWebResponse.GetStream 은 전체 패키지( 패키지 스트림) 또는 패키지의 단일 부분( 파트 스트림)을 나타내는 비트 스트림을 반환합니다.

대부분의 WebResponse 스트림과 달리 Stream.Seek를 사용하여 패키지 스트림을 검색할 수 있습니다. 패키지 스트림을 사용하여 패키지 개체를 만들 수 있습니다.

"http:" 프로토콜을 통해 패키지 리소스로 작업할 때 PackWebRequest 는 파트의 점진적 로드를 지원합니다. 즉, 파트 데이터까지 패키지의 모든 데이터를 로드하지 않고 임의의 순서로 파트 리소스를 가져올 수 있습니다.

PackWebRequest 는 리소스 소비를 위한 기능만 제공합니다. 데이터를 게시하거나 서버에 보내는 데 사용할 수 없습니다.

PackWebRequest 는 현재 비동기 작업(예: BeginGetResponse)을 지원하지 않으며 PackWebRequest 는 중첩된 패키지(앞에서 설명한 "패키지 내의 부분 주소 지정")를 지원하지 않습니다.

The PackageStore

다른 부분에 대한 수많은 참조가 포함된 파트가 있는 패키지를 로드하는 경우 PackageStore를 사용하여 리소스 요청에 대한 응답 시간을 개선하고 네트워크 트래픽을 줄일 수 있습니다. PackageStore는 열려 있는 패키지에 대한 참조의 애플리케이션 로컬 사전입니다. PackageStore에 등록된 각 패키지는 키 URI 값으로 식별됩니다.

PackageStore를 사용하면 PackWebRequest가 해당 패키지에서 다른 리소스가 필요할 때마다 서버 요청을 하지 않고도 패키지에서 필요에 따라 리소스를 가져올 수 있습니다.

PackageStorePackWebRequest 호출의 결과로 자동으로 변경되지 않습니다. 명시적으로 수정해야 합니다. PackageStore에서 열린 패키지에 대한 참조를 추가하거나 제거하는 데 사용되는 두 가지 공용 메서드인 Package.AddPackagePackage.RemovePackage가 있습니다.

PackWebRequest에 설정된 기본 캐시 정책(CacheIfAvailable)을 사용하면 클래스가 PackageStore를 사용하여 패키지를 가져오려고 시도합니다. PackWebRequest는 다음 섹션인 "캐시 정책"에 설명된 대로 캐시 정책을 BypassCache로 설정하여 리소스를 가져올 때 PackageStore의 콘텐츠를 무시하도록 강제할 수 있습니다.

기본 캐시 정책에 따라 패키지 또는 파트의 비트를 가져올 때 PackWebRequest 는 먼저 PackageStore 를 검사하여 "pack:" URI의 기관 구성 요소와 동일한 키로 등록된 패키지가 있는지 확인합니다. PackageStore에 키에 대한 패키지가 포함되어 있지 않으면 PackWebRequest는 "pack:" URI의 기관 구성 요소를 사용하여 리소스를 다운로드하는 내부 WebRequest를 만듭니다.

캐시 정책

캐시 정책은 리소스의 캐시된 복사본을 사용하여 리소스 요청을 채울 수 있는지 여부를 결정하는 데 사용되는 규칙을 정의합니다.

PackWebRequest를 사용하는 경우 명시적으로 설정할 수 있는 두 가지 수준의 캐시 정책이 있습니다. PackWebRequest 자체에 대해 캐시 정책을 설정하여 PackageStore와의 상호 작용을 제어할 수 있습니다. 또한 내부 WebRequest에서 제어하는 캐시에 대해 캐시 정책을 설정할 수도 있습니다. PackWebRequest.GetInternalRequest()를 사용하여 PackWebRequest에서 내부 WebRequest에 액세스할 수 있습니다.

PackWebRequest.CachePolicyCacheOnly로 설정하면 내부 WebRequest에 설정된 캐시 정책이 적용되지 않아 PackageStore에서 패키지 리소스를 가져옵니다.

PackWebRequest.CachePolicyPackageStore의 특정 기능으로 인해 아래에 나열된 정책의 하위 집합을 지원합니다.

표 1. PackWebRequest.CachePolicy 정책

CachePolicy Description
BypassCache 일치하는 URI를 사용하여 PackageStore 항목을 무시합니다.
CacheOnly PackageStore 항목만 고려합니다(데이터를 위해 서버를 쿼리하는 WebRequest를 만들지 않음).
CacheIfAvailable PackageStore를 검사하고, 패키지가 발견되면 패키지를 사용합니다. 그렇지 않으면 패키지 URI("pack:" URI의 내부 URI)로 표시된 리소스에 대한 네트워크 요청을 수행합니다. 이것이 기본값입니다.

PackWebRequest의 경우 다른 모든 CachePolicy 값을 설정하면 WebException이 발생합니다.

점진적 로드

PackWebRequest 는 "http:" 프로토콜을 통해 패키지에 액세스할 때 패키지 부분을 점진적으로 로드할 수 있습니다. 점진적 로드를 사용하면 전체 패키지를 로컬로 사용할 수 있기 전에 애플리케이션이 파트 리소스에 액세스할 수 있습니다. PackWebRequest의 점진적 로드 기능은 자동입니다. 호출 애플리케이션은 개입 없이 향상된 성능을 경험합니다.

점진적 로드는 "http:" 1.1 프로토콜에 정의된 대로 리소스에 대해 "바이트 범위 요청"을 만드는 것을 기반으로 합니다. ZIP 보관 형식은 파일의 물리적 끝에 있는 "중앙 디렉터리"에 중요한 정보를 유지하므로 패키지를 실제 형식으로 저장하는 데 사용되는 ZIP 파일 형식은 이 메커니즘의 이점을 누릴 수 있습니다.

PackWebRequest를 사용하여 전체 패키지를 요청한 후 서비스는 호출자가 검색할 수 있는 스트림을 반환하기 시작합니다. PackWebRequest에서 제공하는 스트림에서 패키지를 열면 호출자는 "http:" 프로토콜을 사용하여 직접 요청을 수행할 때보다 더 빠르게 부품을 가져올 수 있습니다.

URI 평가 및 분해를 위한 서비스

패키지 클래스에서 반환된 관계 파트 이름 식별

Package.GetParts 메서드를 사용하여 가져온 파트의 컬렉션을 관리하는 경우 관계 파트를 식별하여 다른 부분과 별도로 처리할 수 있습니다. PackUriHelper.IsRelationshipPartUri는 부품이 관계 부분인지 여부를 식별하는 데 사용됩니다.

예: 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"

다른 두 가지 PackUriHelper 메서드는 관계 파트 이름을 사용하는 데 사용할 수 있습니다. PackUriHelper.GetRelationshipPartUri 는 원본 파트 이름이 지정된 관계 파트 이름을 반환합니다. PackUriHelper.GetSourcePartUriFromRelationshipPartUri 는 지정된 관계 파트 이름의 원본 파트 이름을 반환합니다.

동등성을 위한 URI 비교

패키지를 생성하거나 사용할 때 부품을 저장하기 위해 캐시를 사용하는 애플리케이션은 동등한 부품 이름에 대한 검사를 수행해야 할 수 있습니다. PackUriHelper.ComparePartUri 메서드는 부품 이름의 동등성을 확인합니다.

예: 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"

두 "pack:" URI의 어휘 동등성을 확인하려면 PackUriHelper.ComparePackUri 메서드를 사용합니다.

예: 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"

"pack:" URI에서 구성 요소 URI 추출

"pack:" URI에서 구성 요소 패키지 URI 및 파트 URI를 추출하려면 각각 PackUriHelper.GetPackageUriPackUriHelper.GetPartUri 메서드를 사용합니다.

예: 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"

예: GetPartUri 예제

//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"

참조

Open Packaging Conventions

URI(Uniform Resource Identifier): 일반 구문

Open XML Paper Specification

국제화된 URI(자원 식별자)