2011-11-22 30 views
15

Di chuyển từ DTD sang XSD và vì lý do nào đó, quá trình chuyển đổi là một sự chuyển đổi gập ghềnh. Tôi hiểu cách xác định lược đồ khi tôi ở trong thẻ gốc <xs:schema>, nhưng vượt qua tiêu đề & công cụ khai báo không gian tên được chứng minh là đặc biệt khó hiểu đối với tôi.Cấu hình tiêu đề và cấu hình không gian tên XML

Tôi đã cố gắng làm theo hướng dẫn được nêu rõ trên W3S nhưng ngay cả hướng dẫn đó dường như giả định rất nhiều kiến ​​thức ở phía trước.

Tôi đoán những gì tôi đang tìm kiếm là một nhà vua giải thích bằng tiếng Anh trong đó thuộc tính làm gì, đi đến đâu, và tại sao:

  • xmlns
  • xmlns: xs
  • xmlns: xsi
  • targetNamespace
  • xsi: schemaLocation

Và trong một số trường hợp tôi thấy các biến thể khác nhau của các thành phần/thuộc tính này, chẳng hạn như xsi có vẻ như có hai ký hiệu khác nhau như xsi:schemaLocation="..."xs:import schemaLocation="...".

Tôi đoán giữa tất cả các biến thể nhỏ này tôi dường như không thể tạo ra đầu hoặc đuôi của từng cái này. Cảm ơn trước vì đã mang lại sự rõ ràng cho sự nhầm lẫn này!

Trả lời

56

Điều đầu tiên bạn cần phải hiểu là các không gian tên XML. Nếu bạn có thời gian để lãng phí, bạn có thể đọc the specification. Tôi thấy đây là một trong những thông số kỹ thuật rõ ràng hơn liên quan đến XML. Nó không quan trọng nếu bạn không hiểu tất cả mọi thứ nó nói, đó là một cơ sở tốt. Nhưng đây là một tóm tắt nhanh chóng.

Các phần tử và thuộc tính XML có tên. Khi bạn nhìn thấy <test att="hello"/>, bạn đang xem xét một phần tử có tên "test", trong đó chúng tôi có một thuộc tính có tên "att". Nhưng đây không hẳn là toàn bộ câu chuyện ...

XML là cú pháp cho phép bạn kết hợp nội dung từ các ngôn ngữ đánh dấu khác nhau. Ví dụ, khi sử dụng XSLT để biến một tài liệu XML thành một trang XHTML, bạn đang xử lý ít nhất ba ngôn ngữ đánh dấu được định nghĩa trong XML: tài liệu đầu vào của bạn, XSLT và XHTML. Những hỗn hợp như vậy sẽ trở nên khá khó khăn nếu mỗi người đã đặt tên riêng cho các phần tử/thuộc tính của nó và không có xung đột nào được cho phép.

Nhập các không gian tên XML. Một không gian tên XML định nghĩa một "hình cầu" trong đó tên phần tử và thuộc tính có ngữ nghĩa thực tế. Phần tử "mẫu" có ý nghĩa được xác định rõ trong không gian tên XSLT. Phần tử "complexType" có ý nghĩa được xác định rõ trong không gian tên lược đồ XML. Nếu bạn muốn sử dụng ngôn ngữ đánh dấu của riêng bạn bằng cách sử dụng XML, thì điều đó có thể được cung cấp cho bạn trong một không gian tên khác.

Để đảm bảo không gian tên là duy nhất, bạn sẽ cần cung cấp một số số nhận dạng duy nhất. Đặc điểm kỹ thuật được giải quyết về việc sử dụng các URI, thường xuyên nhất dưới dạng một URL HTTP. Lý do cho việc này rất đơn giản: các URL như vậy có xu hướng là số nhận dạng duy nhất tốt. Nhưng nó cũng là một nguyên nhân rất phổ biến cho sự nhầm lẫn bởi vì mọi người nghĩ rằng các URL thực sự giữ ý nghĩa hoặc sẽ được truy cập qua mạng trong quá trình xử lý XML. Biết rõ rằng đây không phải là trường hợp! URL không bắt buộc phải trỏ đến bất kỳ tài nguyên hiện có nào. Nó sẽ không đi qua bất kỳ chuyển đổi hoặc được giải quyết đến một địa chỉ mạng.Ngay cả khi hai URL sẽ trỏ đến cùng một điều, thì thời điểm chúng khác nhau theo một ký tự, chúng được coi là các không gian tên khác nhau. Một định danh vùng tên chỉ là một chuỗi và một ký tự phân biệt chữ hoa chữ thường. Chỉ có bấy nhiêu thôi.

Với việc giới thiệu các không gian tên, tên của một phần tử hoặc thuộc tính XML đột nhiên bao gồm hai phần: một vùng tên và một tên cục bộ. "Thử nghiệm" trong <test/> chỉ là tên địa phương. Cái gọi là "tên đủ điều kiện" bao gồm một sự kết hợp vô hình của không gian tên và tên địa phương. Đôi khi ký hiệu {namespace URI}local-name được sử dụng, nhưng đó không hơn quy ước.

Vì vậy, bây giờ chúng tôi cần có khả năng sử dụng không gian tên trong tài liệu XML. Để khai báo một không gian tên, XML có một cơ chế mã hóa cứng. Nó sử dụng chuỗi đặc biệt xmlns để cho phép khai báo vùng tên. Nó có thể được thực hiện theo một trong hai cách: liên kết không gian tên với một tiền tố, hoặc khai báo nó như là không gian tên mặc định.

Khi liên kết với tiền tố, biểu mẫu có dạng như sau: xmlns:prefix="namespace URI". Dưới đây là một ví dụ trong một tài liệu XML:

<foo:root xmlns:foo="http://www.foo.com"> 
    <foo:test /> 
</foo:root> 

Bây giờ chúng ta đã bị ràng buộc namespace http://www.foo.com các tiếp đầu ngữ foo. Bất cứ nơi nào tiền tố này được đặt trước tên phần tử hoặc thuộc tính, chúng tôi đều nói rằng chúng là một phần của không gian tên đó.

Điều quan trọng cần lưu ý ở đây là tiền tố thực tế có nghĩa là hoàn toàn không có gì. Tài liệu XML sau đây có ngữ nghĩa giống hệt nhau:

<bar:root xmlns:bar="http://www.foo.com"> 
    <bar:test /> 
</bar:root> 

Tiền tố chỉ đơn thuần là cách thuận tiện để biểu thị không gian tên. Nó giúp chúng tôi không phải sử dụng URI hoàn toàn mọi lúc.

Tiếp theo là không gian tên mặc định. Không gian tên mặc định có thể được khai báo với xmlns="namespace URI". Bạn có thể trừu tượng nghĩ về điều này như là ràng buộc một không gian tên với tiền tố trống. Một lần nữa cùng một tài liệu XML, nhưng lần này không có tiền tố:

<root xmlns="http://www.foo.com"> 
    <test /> 
</root> 

Thao tác này thuận tiện hơn một chút. Vậy tại sao lại có tiền tố? Chúng bắt đầu đóng vai trò khi chúng tôi trộn nội dung từ các không gian tên khác nhau:

<root xmlns="http://www.foo.com"> 
    <so:test xmlns:so="http://stackoverflow.com" /> 
</root> 

Lần này là tài liệu XML khác. Phần tử root của chúng tôi nằm trong không gian tên http://www.foo.com, nhưng phần tử test nằm ở http://stackoverflow.com vì chúng tôi đã ràng buộc tiền tố so với điều đó và sử dụng nó trên test.

Bạn cũng chú ý rằng không gian tên có thể được khai báo trên bất kỳ phần tử nào trong tài liệu XML. Phạm vi của tuyên bố đó (và ràng buộc với tiền tố nếu có) sau đó trở thành thành phần đó và nội dung của nó.

Điều này đôi khi có thể trở nên khó hiểu, thậm chí nhiều hơn vì các khai báo có thể ghi đè lên nhau. Kiểm tra tài liệu này:

<root xmlns="http://www.foo.com"> 
    <test /> 
    <so:test xmlns:so="http://www.stackoverflow.com" xmlns="http://www.bar.com"> 
     <test /> 
    </so:test> 
</root> 

Dành một chút thời gian và tìm ra không gian tên mỗi phần tử nằm trong ... Đó là một bài tập tốt.

root nằm trong không gian tên http://www.foo.com.Phần tử test đầu tiên cũng nằm trong không gian tên đó, vì chúng tôi chưa sử dụng tiền tố nhưng chúng tôi nằm trong phạm vi của không gian tên mặc định đó. Phần tử test thứ hai có tiền tố so nằm trong không gian tên http://www.stackoverflow.com bởi vì đó là những gì chúng ta ràng buộc tiền tố.

Vì vậy, có phần tử thứ nhất, trong cùng là test. Không gian tên là gì? Nó không có tiền tố, vì vậy nó phải nằm trong không gian tên mặc định. NHƯNG, chúng tôi đã thay đổi không gian tên mặc định của chúng tôi trong phần tử thử nghiệm thứ hai! Vì vậy, bây giờ yếu tố bên trong nhất thuộc về không gian tên http://www.bar.com, không phải là http://www.foo.com.

Bối rối? Chỉ cần nhớ những điều sau:

  • Không gian tên chỉ là một chuỗi. URI được sử dụng như một cách thuận tiện để có số nhận dạng duy nhất.
  • Tiền tố được sử dụng để đại diện cho không gian tên, nhưng tên của nó không có ý nghĩa gì cả. Chỉ cần nghĩ về nó như một trình giữ chỗ.
  • Bạn có thể đặt không gian tên mặc định. Tất cả các phần tử trong phạm vi của nó không có tiền tố thì trở thành một phần của nó.

Phew. Bây giờ, vào Lược đồ XML của W3C. Tất cả điều này liên quan đến nó như thế nào?

Vâng, đối với người mới bắt đầu Lược đồ XML chính nó là một ngôn ngữ đánh dấu được xác định trong XML. Vì vậy, nó đứng để lý do rằng nó được không gian tên riêng của mình. Và không gian tên đó chính thức là http://www.w3.org/2001/XMLSchema. Nếu bạn viết rằng S là trường hợp thấp hơn, nó sai. Bắt đầu thấy lý do tại sao một số người thực sự ghét không gian tên?

Ba tài liệu sau đây là giống hệt nhau:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
</xsd:schema> 

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
</xs:schema> 

<schema xmlns="http://www.w3.org/2001/XMLSchema"> 
</schema> 

Tất cả những gì quan trọng là chúng ta đang sử dụng công cụ từ không gian tên XML Schema. Tuy nhiên, theo quy ước, mọi người có xu hướng sử dụng tiền tố xs hoặc xsd trong Lược đồ XML.

Khi chúng tôi có tài liệu XML, chúng tôi có thể muốn chỉ định vị trí của (các) lược đồ cho nó. Nhiều hơn một lược đồ có thể có liên quan cho một tài liệu XML, bởi vì như chúng ta đã nói các ngôn ngữ có thể được trộn lẫn trong XML. Để nói rằng một tài liệu XML là một thể hiện của một lược đồ, một lần nữa có một không gian tên đặc biệt có sẵn: http://www.w3.org/2001/XMLSchema-instance. Theo quy ước, chúng tôi có xu hướng ràng buộc không gian tên này với tiền tố xsi. Nhưng một lần nữa, điều này không bắt buộc.

Có một vài thuộc tính được xác định trong không gian tên đối tượng lược đồ đó. Trong số đó là schemaLocationnoNamespaceSchemaLocation. Hãy xem tài liệu này:

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.foo.com/schema"> 
</root> 

Điều gì sẽ xảy ra ở đó? Trước tiên, chúng tôi đã tuyên bố rằng chúng tôi đang ràng buộc tiền tố xsi vào không gian tên http://www.w3.org/2001/XMLSchema-instance. Sau đó, chúng tôi đã sử dụng một thuộc tính trong không gian tên đó: noNamespaceSchemaLocation. Thuộc tính đó cho chúng ta biết vị trí của lược đồ để xác nhận các phần của tài liệu không nằm trong bất kỳ vùng tên cụ thể nào. Tài liệu XML sau đây hoàn toàn giống nhau, theo ngữ nghĩa:

<root xmlns:huh="http://www.w3.org/2001/XMLSchema-instance" huh:noNamespaceSchemaLocation="http://www.test.com/schema"> 
</root> 

Hãy nhớ rằng, tên tiền tố không có ý nghĩa. Chúng là phần giữ chỗ. Vậy, cái gì với thuộc tính noNamespaceSchemaLocation? Về cơ bản, nó cho chúng ta biết nơi chúng ta có thể định vị một lược đồ.Bây giờ trái với một URI không gian tên, điều này chắc chắn là một cái gì đó có thể được sử dụng để lấy các thứ từ một mạng hoặc lưu trữ cục bộ. Một bộ xử lý XML hợp lệ hóa với một lược đồ được khai báo trong một tài liệu có thể cố gắng lấy nó.

Sau đó, có thực tế là nó được gọi là noNamespaceSchemaLocation. Một lược đồ định nghĩa một "không gian tên đích". Điều này có nghĩa là không gian tên nào mà các phần tử và các thuộc tính mà nó định nghĩa là một phần của. Nhưng không gian tên đích có thể bị bỏ qua. Trong trường hợp đó, chúng ta có một lược đồ cho các tài liệu XML không có không gian tên. Lược đồ như vậy có thể được gọi với noNamespaceSchemaLocation.

Trong nhiều trường hợp, một lược đồ sẽ thực sự xác định một không gian tên. Để nói lược đồ nào thuộc về không gian tên nào, chúng ta có thể sử dụng thuộc tính khác từ không gian tên http://www.w3.org/2001/XMLSchema-instance: schemaLocation. Thuộc tính đó có thể chứa các cặp (cách nhau bởi dấu cách) của URI không gian tên và URI lược đồ. Giả sử chúng ta có lược đồ cho không gian tên http://www.foo.com tại số http://www.myschemas.com/foo-schema. Sau đó, chúng ta có thể nói rằng như sau:

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.foo.com http://www.myschemas.com/foo-schema"> 
</root> 

Dưới đây là một ví dụ về nhiều cặp namespace-vị trí:

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.foo.com http://www.myschemas.com/foo-schema http://www.bar.com http://www.randomschemas.com/bar-schema"> 
</root> 

Những gì bạn cần nhớ ở đây là http://www.w3.org/2001/XMLSchema-instance cụ này là để sử dụng trong tài liệu XML được các sơ đồ của các lược đồ. Không gian tên http://www.w3.org/2001/XMLSchema là không gian tên được sử dụng để tự định nghĩa lược đồ.


Vì vậy, bây giờ chúng tôi đang ở trong cổ của chúng tôi trong URI và thuộc tính kỳ lạ với ý nghĩa đặc biệt. Đó là điều có không gian tên: chúng trông rất phức tạp cho đến khi bạn tìm ra chúng đơn giản như thế nào. Chỉ cần theo dõi sát xem tiền tố nào bị ràng buộc với URI không gian tên nào và biết URI đó định nghĩa cái gì.

Còn hai điều nữa về lược đồ tôi cần giải quyết cho câu hỏi của bạn: xs:importxs:include. Lưu ý cách tôi đã sử dụng quy ước tiền tố xs ở đây, vì chúng ta đang nói về Lược đồ XML của W3C.

Yếu tố bao gồm có thể được sử dụng để kết hợp các lược đồ với cùng một không gian tên đích. Về cơ bản nó cho phép chúng ta mô đun hóa các lược đồ thành các phần nhỏ hơn và đặt chúng lại với nhau.

Phần tử nhập không giống nhau, nhưng đối với các lược đồ với các không gian tên đích khác nhau. Điều này cho phép chúng tôi kết hợp các lược đồ cho các ngôn ngữ đánh dấu khác nhau.


Vì vậy, để tóm tắt:

  • xmlns: dùng để xác định một không gian tên mặc định.
  • xmlns:prefix: được sử dụng để liên kết không gian tên với prefix.
  • http://www.w3.org/2001/XMLSchema: không gian tên cho Lược đồ XML. Theo quy ước thường bị ràng buộc với tiền tố xs, nhưng điều này không bắt buộc cũng không được thực hiện tự động.
  • http://www.w3.org/2001/XMLSchema-instance: không gian tên xác định một loạt những điều hữu ích để khai báo chi tiết về cách một tài liệu XML là một thể hiện của lược đồ. Theo quy ước thường bị ràng buộc vào tiền tố xsi, nhưng điều này không bắt buộc cũng không được thực hiện tự động.
  • targetNamespace: thuộc tính có thể được sử dụng trong Lược đồ XML (trên phần tử gốc) để chỉ định không gian tên nào là định nghĩa lược đồ.
  • schemaLocation: một trong các thuộc tính được xác định bởi không gian tên http://www.w3.org/2001/XMLSchema-instance, được sử dụng để chỉ ra nơi một hoặc nhiều lược đồ có thể được tìm thấy cho một hoặc nhiều không gian tên.

Lời khuyên cuối cùng của tôi: tìm một số cách thuận tiện để xác thực tài liệu đối với các lược đồ và phát xung quanh một chút. Thử nghiệm với không gian tên, bao gồm và nhập. Tạo tài liệu bằng cách sử dụng nhiều không gian tên và thử phạm vi.

Sau đó, kiểm tra thông số kỹ thuật của chính XML, các không gian tên XML và Lược đồ XML. Đó là đọc sách hardcore, nhưng nếu bạn thực hiện theo cách của bạn thông qua nó, bạn sẽ đạt được một sự hiểu biết rằng nhiều người vẫn có vẻ bỏ lỡ sau nhiều năm sử dụng XML. Cuối cùng tất cả sẽ có ý nghĩa.

Chúc may mắn!

+3

Đây là sử thi - phải là câu trả lời cuối cùng cho loại câu hỏi này, nếu chồng tràn hỗ trợ tính năng này. Cảm ơn bạn đã đăng bài này tôi đã học được rất nhiều và có thể thấy tại sao câu trả lời của tôi thực sự bị giới hạn. –

+0

@hugh Nó thậm chí không hoàn thành ... Đối với các thuộc tính, tiền tố có một số quy tắc sai lệch. Chúng không đủ điều kiện theo mặc định. Nhưng tôi không hoàn toàn chắc chắn liệu chúng có đặt chúng vào không gian tên của phần tử hay không, vì vậy tôi cẩn thận để đưa ra những tuyên bố về nó. Và có nhiều thứ tôi có thể đề cập, nhưng sự thật là chỉ có các thông số kỹ thuật mới có thể cung cấp câu trả lời dứt khoát. –

+0

G_H rất hiếm khi ai đó dành thời gian trả lời câu hỏi một cách thấu đáo như thế này. Cảm ơn bạn! – IAmYourFaja

2

Trong câu trả lời cho thắc mắc của bạn:

  1. xmlns - một giá trị duy nhất được sử dụng trong các văn bản ví dụ để chỉ ra các lược đồ XML là một thể hiện của (hoặc những gì schema nó sẽ xác nhận đối với). Mặc dù không gian tên không xác định tệp lược đồ thực tế, nên có một lược đồ xác định không gian tên này.
  2. xmlns:xs - được gọi là tiền tố không gian tên và theo quy ước được sử dụng trong tài liệu ví dụ để cho biết loại được sử dụng trong XML đến từ đâu. Bạn có thể nghĩ về điều này giống như using trong C# hoặc imports trong VB. Ví dụ: xmlns:xs="http://mySharedTypes" nói rằng trong XML này, một số loại của tôi đến từ không gian tên "http: // mySharedTypes" và các loại này sẽ được bắt đầu bằng "xs".
  3. xmlns:xsi - như trên. Infact các tiền tố xs và xsi theo quy ước được sử dụng khi tham chiếu các không gian tên lược đồ W3C http://www.w3.org/2001/XMLSchemahttp://www.w3.org/2001/XMLSchema-instance. Tuy nhiên, các tiền tố không gian tên này chỉ là quy ước và thực sự có thể là bất kỳ thứ gì.
  4. targetNamespace - giá trị duy nhất bạn đặt trong định nghĩa lược đồ, cung cấp các loại bạn xác định trong lược đồ không gian tên của chúng. Vì vậy, nếu ai đó muốn sử dụng các loại trong lược đồ của bạn thì chúng phải bao gồm thuộc tính xmlns với các giá trị giống như không gian targetNames của bạn.
  5. xs:import schemaLocation - Đây thường là đường dẫn tương đối với giản đồ khác, mặc dù không phải tất cả các bộ xử lý xml đều nhận ra nó. Vì vậy, bạn có thể tùy chọn liên kết đến giản đồ khác trong số xs:import của bạn dưới dạng loại phím tắt cho chính tệp đó. Thuộc tính khác trong quá trình nhập là targetNamespace lược đồ, là bắt buộc.
  6. xsi:schemaLocation - Mặc dù tên này có cùng tên với thuộc tính nhập không có cùng định nghĩa. Theo quy ước, tiền tố không gian tên xsi đề cập đến các kiểu từ không gian tên http://www.w3.org/2001/XMLSchema-instance, được sử dụng bên trong các tài liệu cá thể, chứ không phải là các tài liệu lược đồ.

Xin lỗi nếu điều trên không rõ ràng, đó là một chút câu hỏi mở và có rất nhiều tài liệu bạn có thể viết cho bất kỳ một trong những điểm này. Nếu bạn cần sự rõ ràng về bất kỳ điểm nào, vui lòng hỏi - Tôi sẽ sẵn lòng cung cấp, hoặc tạo ra một câu hỏi mới với phạm vi hẹp hơn.

+0

Thông tin này không hoàn toàn chính xác. 'xmlns' chỉ ra một không gian tên mặc định, nó không có gì để làm bất cứ điều gì với việc chỉ ra một lược đồ. Có một số sai lầm khác. Chúng có thể nhỏ, nhưng khi nói đến các không gian tên và Lược đồ XML, điều nhỏ nhất có thể nhanh chóng trở nên khó hiểu. –

+0

Cảm ơn bạn rất nhiều hugh; đây là giải thích tốt nhất, kỹ lưỡng nhất và dễ hiểu về công cụ này mà tôi đã gặp phải. Một ý nghĩ cuối cùng: nếu bạn đang xây dựng XML tuân thủ lược đồ khi đang bay (trong bộ nhớ, như, nói, một chuỗi): bạn có luôn luôn cần đặt các công cụ xmlns, xs, xsi, v.v. trong "chuỗi cá thể" này không để xác thực nó, hoặc có thể chỉ cần nói cho một trình phân tích cú pháp lược đồ nào để xác nhận hợp lệ XML; sau đó bao gồm tất cả các def đó trong lược đồ? – IAmYourFaja

+0

@G_H Cảm ơn bạn đã bình luận. Vui lòng chỉnh sửa câu trả lời của tôi hoặc vui lòng cho biết những điểm không chính xác khác và tôi sẽ kết hợp vào câu trả lời của tôi. –

0
  • xmlns="uri1"xmlns:whatever="uri2" là nút không gian tên chứ không phải thuộc tính. Vai trò của họ là để nói rằng khi bạn thấy phần tử trong tài liệu XML của bạn có tên là whatever:myElement, thì phần tử đó thuộc về không gian tên "bất cứ điều gì". Điều này "bất kỳ không gian tên" được xác định bởi các uri khai báo trong nút không gian tên.
  • targetNamespace là một thuộc tính. Nó chứa một URI xác định các phần tử, kiểu và nhóm mà bạn định nghĩa trong lược đồ của bạn.
  • xsi: schemaLocation hoàn toàn khác. Đó là một thuộc tính cho phép các trình phân tích cú pháp XML tìm thấy lược đồ được đính kèm với một cá thể XML. Bạn không cần nó trong lược đồ.
  • Với xs:import bạn có thể nhập lược đồ từ không gian tên khác nhau để sử dụng các phần tử và loại của chúng trong lược đồ của riêng bạn. Khi sử dụng xs:import, lược đồ đã nhập và lược đồ nhập phải có không gian tên khác nhau. Sử dụng xs:include nếu đó là cùng một không gian tên.
Các vấn đề liên quan