Các thuộc tính này đặc biệt vì loại và không phải vì tên của chúng.
ID trong XML
Mặc dù nó rất dễ dàng để nghĩ về các thuộc tính như name="value"
với giá trị được trở thành một chuỗi đơn giản, đó không phải là toàn bộ câu chuyện - đó cũng là một loại thuộc tính gắn liền với thuộc tính.
Điều này dễ dàng đánh giá cao khi có một Lược đồ XML có liên quan, vì Lược đồ XML hỗ trợ các kiểu dữ liệu cho cả các phần tử XML và các thuộc tính XML. Các thuộc tính XML được định nghĩa là một kiểu đơn giản (ví dụ: xs: string, xs: integer, xs: dateTime, xs: anyURI). Các thuộc tính đang được thảo luận ở đây được xác định với xs:ID
kiểu dữ liệu dựng sẵn (xem section 3.3.8 of the XML Schema Part 2: Datatypes).
<xs:element name="foo">
<xs:complexType>
...
<xs:attribute name="bar" type="xs:ID"/>
...
</xs:complexType>
</xs:element>
Mặc dù DTD không hỗ trợ kiểu dữ liệu phong phú về XML Schema, nó hỗ trợ một tập hạn chế về kiểu thuộc tính (được định nghĩa trong section 3.3.1 of XML 1.0). Các thuộc tính đang được thảo luận ở đây được xác định với loại thuộc tính của ID
.
<!ATTLIST foo bar ID #IMPLIED>
Với lược đồ XML ở trên hoặc DTD, phần tử sau sẽ được xác định bằng giá trị ID của "xyz".
<foo bar="xyz"/>
Mà không biết Schema XML hoặc DTD, không có cách nào để nói với một ID là gì và những gì không:
- Thuộc tính với tên của "id" không nhất thiết phải có một loại thuộc tính ID; và
- Thuộc tính có tên không phải là "id" có thể có loại thuộc tính của ID!
Để cải thiện tình trạng này, sau đó xml:id
được phát minh (xem xml:id W3C Recommendation). Đây là thuộc tính luôn có cùng tiền tố và tên và được coi là thuộc tính với loại thuộc tính ID. Tuy nhiên, cho dù nó sẽ phụ thuộc vào phân tích cú pháp được sử dụng là nhận thức của xml:id
hay không. Vì nhiều trình phân tích cú pháp ban đầu được viết trước khi xml:id
được xác định, nó có thể không được hỗ trợ.
ID trong Java
Trong Java, getElementById()
tìm thấy yếu tố bằng cách tìm kiếm các thuộc tính của loại ID, không cho các thuộc tính với tên của "id".
Trong ví dụ trên, getElementById("xyz")
sẽ trở lại mà foo
yếu tố, mặc dù tên của thuộc tính trên nó không phải là "id" (giả sử DOM biết rằng bar
có một loại thuộc tính ID).
Vậy làm thế nào để DOM biết loại loại thuộc tính thuộc tính nào? Có ba cách:
- Cung cấp một XML Schema để phân tích cú pháp (example)
- Cung cấp một DTD để phân tích cú pháp
- Rõ ràng chỉ vào DOM rằng nó được coi là một loại thuộc tính của ID.
Lựa chọn thứ ba được thực hiện bằng cách sử dụng setIdAttribute()
hoặc setIdAttributeNS()
hoặc setIdAttributeNode()
phương pháp trên org.w3c.dom.Element
class.
Document doc;
Element fooElem;
doc = ...; // load XML document instance
fooElem = ...; // locate the element node "foo" in doc
fooElem.setIdAttribute("bar", true); // without this, 'found' would be null
Element found = doc.getElementById("xyz");
Điều này phải được thực hiện cho mỗi nút phần tử có một trong các loại thuộc tính này trên chúng. Không có phương thức tích hợp đơn giản nào để làm cho tất cả các lần xuất hiện của thuộc tính với tên đã cho (ví dụ: "id") là loại thuộc tính ID.
Cách tiếp cận thứ ba này chỉ hữu ích trong các tình huống trong đó mã gọi getElementById()
tách biệt với việc tạo DOM. Nếu đó là cùng một mã, nó đã tìm thấy phần tử để thiết lập thuộc tính ID sao cho nó không có khả năng cần gọi getElementById()
.
Ngoài ra, hãy lưu ý rằng các phương pháp đó không nằm trong đặc tả DOM gốc. getElementById
được giới thiệu trong DOM level 2.
ID trong XPath
XPath trong câu hỏi ban đầu đã cho kết quả một vì nó chỉ phù hợp với các thuộc tính tên.
Để phù hợp trên loại giá trị ID thuộc tính, hàm XPath id
cần phải được sử dụng (nó là một trong những Node Set Functions from XPath 1.0):
id("xyz")
Nếu đó đã được sử dụng, XPath sẽ trao kết quả tương tự như getElementById()
(tức là không tìm thấy kết quả phù hợp).
ID trong XML tiếp tục
Hai tính năng quan trọng của ID nên được đánh dấu.
Thứ nhất, giá trị của tất cả các thuộc tính của loại thuộc tính ID phải là duy nhất cho toàn bộ tài liệu XML. Trong ví dụ sau, nếu personId
và companyId
cả hai đều có loại thuộc tính ID, sẽ là lỗi khi thêm một công ty khác với companyId
của id24601, bởi vì nó sẽ trùng lặp với giá trị ID hiện tại. Mặc dù tên thuộc tính khác nhau, nhưng nó là loại thuộc tính quan trọng.
<test1>
<person personId="id24600">...</person>
<person personId="id24601">...</person>
<company companyId="id12345">...</company>
<company companyId="id12346">...</company>
</test1>
Thứ hai, thuộc tính được định nghĩa trên các yếu tố chứ không phải là toàn bộ tài liệu XML. Vì vậy, các thuộc tính có cùng tên thuộc tính trên các phần tử khác nhau có thể có các thuộc tính thuộc tính khác nhau thuộc tính. Trong tài liệu ví dụ XML sau đây, nếu chỉ alpha/@bar
có một loại thuộc tính của ID (và không có thuộc tính khác là), getElementById("xyz")
sẽ trở lại một yếu tố, nhưng getElementById("abc")
sẽ không (kể từ beta/@bar
không phải là của loại thuộc tính ID). Ngoài ra, không phải là lỗi đối với thuộc tính gamma/@bar
để có cùng giá trị với alpha/@bar
, giá trị đó không được xem xét tính duy nhất của ID trong tài liệu XML vì nó không phải là loại thuộc tính ID.
<test2>
<alpha bar="xyz"/>
<beta bar="abc"/>
<gamma bar="xyz"/>
</test2>
+1 Nice câu trả lời! Tôi đã học được một cái gì đó mới ngày hôm nay. –
Thật không may, liên kết đến ví dụ lược đồ đã chết ngay bây giờ. – ferkulat