2009-08-20 34 views
42

Tôi đang sử dụng tùy chọn --schema xmllint để xác thực XML của tôi trông như thế nàyxsd: loại phần tử boolean chấp nhận "true" nhưng không chấp nhận "True". Làm thế nào tôi có thể làm cho nó chấp nhận nó?

<XML> 
<Active>True</Active> 
</XML> 

Trong file schema của tôi, tôi có dòng sau mô tả các yếu tố tích cực.

<xsd:element name="Active" type="xsd:boolean" /> 

Khi tôi chạy xmllint, tôi nhận được thông báo lỗi nói rằng

/tmp/schema_validation.xml:73: yếu tố tích cực: Schemas giá trị lỗi: tử 'Hoạt động': 'True' không phải là một giá trị hợp lệ của loại nguyên tử 'xs: boolean'.

Khi tôi thay đổi XML để

<Active>true</Active> 

Sau đó, thông báo lỗi sẽ biến mất. Vì vậy, có vẻ như xsd: boolean có nghĩa là tất cả chữ thường là "true/false" nhưng không phải là "True/False" thành xmllint .. Câu hỏi của tôi là, làm cách nào để xmllint chấp nhận "True" cho xsd: boolean kiểu? Hoặc có những công cụ khác nhau mà tôi có thể sử dụng để xác thực XML này không? Thay đổi XML hoặc lược đồ không phải là lựa chọn của tôi vào thời điểm này.

Cảm ơn!

+0

Nếu thay đổi mã nguồn XML hoặc giản đồ không phải là một lựa chọn, sau đó tôi sẽ đề nghị chạy XML nguồn thông qua một phép biến đổi để bình thường hóa các giá trị boolean với các giá trị hợp lệ XSD thích hợp. –

+0

Tôi đã nghĩ đến việc đó, nhưng tôi đã sợ phải sửa đổi các giá trị chỉ xảy ra là "Đúng". Đối với eample, nếu một phần tử được gọi là "Description" xảy ra có chứa giá trị "True", thì tôi không muốn điều đó được chuyển thành "true".Tôi không nghĩ rằng có bất kỳ cách nào để biết được yếu tố nào để áp dụng bình thường hóa hay không. –

+13

bạn cần phải đi ngược dòng: ngừng tạo XML không hợp lệ tại nguồn của nó. – Cheeso

Trả lời

88

Bạn không thể.

Theo số XML Schema specification, boolean là true hoặc false. True là không hợp lệ:

 

    3.2.2.1 Lexical representation 
    An instance of a datatype that is defined as ·boolean· can have the 
    following legal literals {true, false, 1, 0}. 

    3.2.2.2 Canonical representation 
    The canonical representation for boolean is the set of 
    literals {true, false}. 

Nếu công cụ mà bạn đang sử dụng thực sự xác nhận đối với các tiêu chuẩn XML Schema, thì bạn không thể thuyết phục nó để chấp nhận True cho một boolean.

+5

Cảm ơn. Thật tuyệt khi biết rằng hoàn toàn không có cách nào để xác định lại xsd: boolean –

+2

Nói cách khác - nếu phần mềm ngược dòng tạo ra True cho một cái gì đó được định nghĩa là boolean Lược đồ XML, thì thực ra chúng không tạo ra XML, trông tương tự. Bộ phận tiếp thị của họ sau đó không nên tuyên bố họ sử dụng XML, vì bây giờ họ đã vô hiệu hóa điểm của việc sử dụng XML - khả năng tái sử dụng các trình phân tích cú pháp phổ biến vì mục đích hiệu quả. –

+3

Tôi sẽ khác với @Oskar tại đây. Có những công cụ yêu cầu để tạo ra XML nhưng trên thực tế thì không, bởi vì những gì chúng tạo ra không được định dạng đúng. Nhưng ở đây bạn dường như có phần mềm ngược dòng tạo XML mà * là * được hình thành tốt, nhưng không hợp lệ theo Lược đồ XML của nó. Nó vẫn là XML. Họ không thể tuyên bố rằng nó phù hợp với Lược đồ XML mà bạn đang sử dụng. – LarsH

46

xs:boolean được xác định trước về loại dữ liệu mà nó chấp nhận. Nếu bạn cần một cái gì đó khác nhau, bạn phải xác định liệt kê riêng bạn:

<xs:simpleType name="my:boolean"> 
    <xs:restriction base="xs:string"> 
     <xs:enumeration value="True"/> 
     <xs:enumeration value="False"/> 
    </xs:restriction> 
    </xs:simpleType> 
+0

Cảm ơn! Tôi sẽ yêu cầu một cái gì đó giống như này là một phần của lược đồ để tôi có thể làm việc xung quanh này cho bây giờ. –

2

Nếu bạn đang ở trên Linux, hoặc có Cygwin có sẵn trên Windows, bạn có thể chạy XML đầu vào thông qua một kịch bản sed đơn giản mà sẽ thay thế <Active>True</Active> với <Active>true</Active>, như vậy:

cat <your XML file> | sed 'sX<Active>True</Active>X<Active>true</Active>X' | xmllint --schema - 

Nếu bạn không, bạn vẫn có thể sử dụng một pocessor không xác nhận XSLT (Xalan, saxon vv) để chạy một chuyển đổi XSLT đơn giản trên đầu vào, và chỉ sau đó ống nó để xmllint.

gì xsl nên chứa một cái gì đó như dưới đây, cho ví dụ bạn liệt kê ở trên (bộ xử lý XSLT nên 2.0 có khả năng):

<?xml version="1.0"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:template match="/"> 
    <xsl:for-each select="XML"> 
     <xsl:for-each select="Active"> 
      <xsl:value-of select=" replace(current(), 'True','true')"/> 
     </xsl:for-each> 
    </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 
+0

Hãy coi chừng: Tôi nghi ngờ có bất kỳ kịch bản "sed' đơn giản" nào đủ mạnh để thực hiện một cách thay thế chính xác như thế này trên một tệp XML --- của bạn thì không. – JonBrave

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