2009-11-05 29 views
17

của chúng tôi ứng dụng C++ đọc dữ liệu cấu hình từ file XML giống như thế này:Tôi có thể thực thi thứ tự các thuộc tính XML bằng cách sử dụng lược đồ không?

<data> 
<value id="FOO1" name="foo1" size="10" description="the foo" ... /> 
<value id="FOO2" name="foo2" size="10" description="the other foo" ... /> 
... 
<value id="FOO300" name="foo300" size="10" description="the last foo" ... /> 
</data> 

Cấu hình ứng dụng hoàn chỉnh bao gồm ~ 2500 của những tập tin XML (mà dịch thành hơn 1,5 triệu chìa khóa/giá trị thuộc tính cặp) . Các tệp XML đến từ nhiều nguồn/nhóm khác nhau và được xác thực đối với một lược đồ. Tuy nhiên, đôi khi <value/> nút trông như thế này:

<value name="bar1" id="BAR1" description="the bar" size="20" ... /> 

hay này:

<value id="BAT1" description="the bat" name="bat1" size="25" ... /> 

Để thực hiện quá trình này nhanh chóng, chúng tôi đang sử dụng Expat để phân tích các tài liệu XML. Expat cho thấy nhiều thuộc tính như một mảng - như thế này:

void ExpatParser::StartElement(const XML_Char* name, const XML_Char** atts) 
{ 
// The attributes are stored in an array of XML_Char* where: 
// the nth element is the 'key' 
// the n+1 element is the value 
// the final element is NULL 
for (int i = 0; atts[i]; i += 2) 
{ 
    std::string key = atts[i]; 
    std::string value = atts[i + 1]; 
    ProcessAttribute (key, value); 
} 
} 

này đặt tất cả trách nhiệm lên chức năng ProcessAttribute() của chúng tôi để đọc các 'chìa khóa' và quyết định phải làm gì với các giá trị. Việc lập hồ sơ ứng dụng đã chỉ ra rằng ~ 40% tổng thời gian phân tích cú pháp XML đang xử lý các thuộc tính này theo tên/chuỗi.

Quy trình tổng thể có thể tăng tốc đột ngột nếu tôi có thể đảm bảo/thực thi thứ tự các thuộc tính (đối với người mới bắt đầu, không so sánh chuỗi trong ProcessAttribute()). Ví dụ, nếu thuộc tính 'id' là luôn thuộc tính 1 chúng ta có thể đối phó với nó trực tiếp:

void ExpatParser::StartElement(const XML_Char* name, const XML_Char** atts) 
{ 
// The attributes are stored in an array of XML_Char* where: 
// the nth element is the 'key' 
// the n+1 element is the value 
// the final element is NULL 
ProcessID (atts[1]); 
ProcessName (atts[3]); 
//etc. 
} 

Theo thông số kỹ thuật schema W3C, tôi có thể sử dụng <xs:sequence> trong một lược đồ XML để thực thi sắc lệnh của các yếu tố - nhưng nó dường như không hoạt động cho các thuộc tính - hoặc có lẽ tôi đang sử dụng nó không chính xác:

<xs:element name="data"> 
<xs:complexType> 
    <xs:sequence> 
    <xs:element name="value" type="value_type" minOccurs="1" maxOccurs="unbounded" /> 
    </xs:sequence> 
</xs:complexType> 
</xs:element> 

<xs:complexType name="value_type"> 
<!-- This doesn't work --> 
<xs:sequence> 
    <xs:attribute name="id" type="xs:string" /> 
    <xs:attribute name="name" type="xs:string" /> 
    <xs:attribute name="description" type="xs:string" /> 
</xs:sequence> 
</xs:complexType> 

Có cách nào để thực thi thứ tự thuộc tính trong tài liệu XML không? Nếu câu trả lời là "không" - có thể ai đó có thể đề xuất một giải pháp thay thế không mang hình phạt hiệu suất thời gian chạy lớn?

+2

Tại sao bạn đi với các thuộc tính và không foo1 foo1 Đây là mô tả? Bạn có thể chỉ định thứ tự của các phần tử, vậy tại sao không sử dụng chúng? – jmucchiello

+0

+1 Đây là một câu hỏi rất hay (và thú vị). –

Trả lời

30

Theo đặc tả xml,

thứ tự của thông số kỹ thuật thuộc tính trong một sự khởi đầu-tag hoặc thẻ phần tử rỗng là không đáng kể

Bạn có thể kiểm tra xem nó ở section 3.1

1

Tôi không nghĩ rằng Lược đồ XML hỗ trợ các thuộc tính đó - chỉ được xác định và giới hạn theo tên, ví dụ: chúng phải khớp với một tên cụ thể - nhưng tôi không thấy cách bạn có thể xác định thứ tự cho các thuộc tính đó trong XSD.

Tôi không biết cách nào khác để đảm bảo thuộc tính trên nút XML theo thứ tự cụ thể - không chắc liệu có bất kỳ cơ chế lược đồ XML nào khác như Schematron hoặc Relax NG sẽ hỗ trợ điều đó không ...

+4

Nó không phải là một hạn chế của lược đồ XML mà là của chính XML. Xem bình luận của st.stoqnov. – porges

0

Chỉ cần đoán, nhưng bạn có thể thử thêm use="required" vào từng thông số thuộc tính của mình không?

<xs:complexType name="value_type"> 
<!-- This doesn't work --> 
<xs:sequence> 
    <xs:attribute name="id" type="xs:string" use="required" /> 
    <xs:attribute name="name" type="xs:string" use="required" /> 
    <xs:attribute name="description" type="xs:string" use="required" /> 
</xs:sequence> 
</xs:complexType> 

Tôi tự hỏi liệu trình phân tích cú pháp có bị chậm lại hay không bằng cách cho phép các thuộc tính tùy chọn, khi xuất hiện thuộc tính của bạn sẽ luôn ở đó.

Một lần nữa, chỉ cần đoán.

EDIT: Thông số XML 1.0 nói rằng thứ tự thuộc tính không đáng kể. http://www.w3.org/TR/REC-xml/#sec-starttags

Do đó, XSD sẽ không thực thi bất kỳ thứ tự nào.Nhưng điều đó không có nghĩa là các trình phân tích cú pháp không thể bị lừa làm việc một cách nhanh chóng, vì vậy tôi giữ câu trả lời ở trên được xuất bản trong trường hợp nó thực sự hoạt động.

1

Tôi chắc chắn không có cách nào để thực thi thứ tự thuộc tính trong tài liệu XML. Tôi sẽ giả định rằng bạn có thể nhấn mạnh vào nó thông qua một quá trình kinh doanh hoặc các yếu tố con người khác, chẳng hạn như một hợp đồng hoặc tài liệu khác.

Điều gì sẽ xảy ra nếu bạn giả định rằng thuộc tính đầu tiên là "id" và đã kiểm tra tên để chắc chắn? Nếu có, hãy sử dụng giá trị, nếu không, thì bạn có thể thử lấy thuộc tính theo tên hoặc vứt bỏ tài liệu.

Trong khi không hiệu quả như gọi ra thuộc tính theo thứ tự của nó, một số khác không số lần bạn sẽ có thể đoán rằng các nhà cung cấp dữ liệu của bạn đã phân phối XML đến spec. Thời gian còn lại, bạn có thể thực hiện hành động khác.

2

Câu trả lời không, than ôi. Tôi bị sốc bởi con số 40% của bạn. Tôi cảm thấy khó tin rằng việc biến "foo" thành ProcessFoo mất nhiều thời gian. Bạn có chắc chắn 40% không bao gồm thời gian được đưa đến thực hiện ProcessFoo?

Có thể truy cập các thuộc tính theo tên bằng cách sử dụng tính năng Expat này không? Đó là cách truyền thống hơn để truy cập các thuộc tính. Tôi không nói nó sẽ nhanh hơn, nhưng nó có thể đáng để thử.

+2

'Expat thing' là một trong những phân tích cú pháp nhanh nhất xung quanh .. Đừng sốc, bạn vừa mới được bán bởi MSFT và IBM và nó không mở rộng :-) –

+1

Gary, bạn đã đúng. Tôi không giải thích chính xác những gì hàm ProccessAttribute() thực hiện vì tôi nghĩ nó là chủ đề ngoài câu hỏi gốc ... Chúng tôi đang phân tích các tài liệu XML này khi khởi động ứng dụng và đổ dữ liệu phần tử vào cơ sở dữ liệu sqlite để xử lý sau . API sqlite cho phép ràng buộc các tham số theo chỉ mục - vì vậy nếu tôi có thể tự tin rằng các thuộc tính XML luôn theo cùng thứ tự như các tham số trong câu lệnh Insert, mọi thứ sẽ nhanh hơn nhiều (nhiều). –

0

Từ những gì tôi nhớ lại, Expat là một trình phân tích cú pháp không hợp lệ và tốt hơn cho nó .. vì vậy bạn có thể loại bỏ ý tưởng XSD đó. Không phải là phụ thuộc vào một ý tưởng tốt trong nhiều phương pháp tiếp cận XML (XSD đã bị chỉ trích về trật tự nguyên tố một sự trở lại rất nhiều trong ngày, ví dụ, bởi pro hoặc anti-seller của XML Web Services tại MSFT).

Thực hiện mã hóa tùy chỉnh của bạn và chỉ cần mở rộng logic của bạn để tìm kiếm hoặc tìm kiếm hiệu quả hơn vào nguồn trình phân tích cú pháp. Nó là tầm thường để viết các công cụ xung quanh mã hóa thay thế hiệu quả trong khi che chắn các đại lý phần mềm và người sử dụng từ nó .. bạn muốn làm điều này để nó dễ dàng di chuyển trong khi vẫn giữ khả năng tương thích ngược và đảo ngược. Ngoài ra, hãy sử dụng các ràng buộc kích thước cố định/thuộc tính-name-translation.

[Cân nhắc bản thân may mắn với Expat :) và tốc độ thô của nó. Hãy tưởng tượng cách CLR phát triển các cơ sở mở rộng quy mô XML yêu thích, họ thường gửi 200MB trên dây trong quá trình 'chỉ truy vấn cơ sở dữ liệu' ..]

6

Thuộc tính XML không một đơn hàng, do đó không có lệnh để thực thi .

Nếu bạn muốn thứ gì đó được đặt hàng, bạn cần các phần tử XML. Hoặc một cái gì đó khác với XML. JSON, YAML và bEncode, ví dụ: có cả hai bản đồ (không có thứ tự) và các chuỗi (được sắp xếp theo thứ tự).

4

Như những người khác đã chỉ ra, không, bạn không thể dựa vào thứ tự thuộc tính.

Nếu tôi có bất kỳ quá trình nào liên quan đến 2.500 tệp XML và 1,5 triệu cặp khóa/giá trị, tôi sẽ lấy dữ liệu đó ra khỏi XML và thành một dạng có thể sử dụng được càng sớm càng tốt. Cơ sở dữ liệu, định dạng tuần tự nhị phân, bất cứ điều gì.Bạn không nhận được bất kỳ lợi thế nào từ việc sử dụng XML (ngoài xác nhận hợp lệ lược đồ). Tôi sẽ cập nhật cửa hàng của mình mỗi khi tôi nhận được một tệp XML mới và phân tích cú pháp 1,5 triệu phần tử XML ra khỏi luồng chính của quy trình của tôi.

Các vấn đề liên quan