2013-04-14 16 views
6

Tôi cố gắng để chèn chuỗi sau đây vào một lĩnh vực xml sqlnhân vật xml bất hợp pháp trên SQL Insert

<?xml version="1.0" encoding="UTF-8"?> 
<Response> 
    <Ip>x.x.x.x</Ip> 
    <CountryCode>CA</CountryCode> 
    <CountryName>Canada</CountryName> 
    <RegionCode>QC</RegionCode> 
    <RegionName>Québec</RegionName> 
    <City>Dorval</City> 
    <ZipCode>h9p1j3</ZipCode> 
    <Latitude>45.45000076293945</Latitude> 
    <Longitude>-73.75</Longitude> 
    <MetroCode></MetroCode> 
    <AreaCode></AreaCode> 
</Response> 

Mã chèn trông giống như:

INSERT 
    INTO Traffic(... , xmlGeoLocation, ...) 
    VALUES (
     ... 
     <!--- 
     <cfqueryparam CFSQLType="cf_sql_varchar" value="#xmlGeoLocation#">, 
     ---> 
     '#xmlGeoLocation#', 

     ... 
     ) 

Hai điều xấu xảy ra:

  1. Québec được chuyển thành Quà © bec

  2. tôi nhận được một lỗi nói [Macromedia][SQLServer JDBC Driver][SQLServer]XML parsing: line 8, character 16, illegal xml character

UPDATE:

Dòng kiểm tra đến là ký tự byte chủ yếu là duy nhất.

Ký tự é là ký tự 2 byte. Trong C3A9 đặc biệt

Ngoài ra tôi không có kiểm soát đối với dòng xml đến

+1

Tôi nghĩ rằng máy chủ * sql sử dụng mã hóa utf-16 và khai báo 'utf-8' trong xml là lý do tại sao nó không thành công. FWIW, nếu bạn loại bỏ hoàn toàn việc khai báo 'encoding', hoặc thay đổi nó thành' encoding = "UTF-16" 'chèn thành công trong CF10, với cài đặt" Enable High ASCII characters ... "được bật. (Thay đổi mã hóa của chỉ chuỗi không có hiệu lực.) Tuy nhiên, tôi không biết nếu điều này có bất kỳ tác động tiêu cực phụ. – Leigh

+0

Lưu ý, mã hóa ký tự là * không * sở trường của tôi ;-) Nhận xét của tôi ở trên chỉ dựa trên một vài kiểm tra nhanh. Nó không phải là một câu trả lời chắc chắn, nhưng hy vọng nó có thể giúp chỉ cho bạn đi đúng hướng. – Leigh

+0

Bạn nhận được XML như thế nào? Nghe có vẻ như tôi không nói với CF rằng đó là UTF-8. –

Trả lời

1

Có một cái nhìn tại link này từ w3, nó cho tôi biết rằng:

In HTML, there is a list of some built-in character names like &eacute; for é but XML does not have this. In XML, there are only five built-in character entities: &lt; , &gt; , &amp; , &quot; and &apos; for <, >, &, " and ' respectively. You can define your own entities in a Document Type Definition, or you can use any Unicode character (see next item).

In HTML, there are also numeric character references, such as &#38; for &. You can refer to any Unicode character, but the number is decimal, whereas in the Unicode tables the number is usually in hexadecimal. XML also allows hexadecimal references: &#x26; for example.

Điều này khiến tôi tin rằng, &#xE9; có thể hoạt động đối với nhân vật é.

Ngoài ra các thông tin tại link này từ Microsoft khẳng định rằng:

SQLXML 4.0 relies upon the limited support for DTDs provided in SQL Server. SQL Server allows for an internal DTD in xml data type data, which can be used to supply default values and to replace entity references with their expanded contents. SQLXML passes the XML data "as is" (including the internal DTD) to the server. You can convert DTDs to XML Schema (XSD) documents using third-party tools, and load the data with inline XSD schemas into the database.

Nhưng tất cả điều này không giúp bạn nếu bạn không có quyền kiểm soát các dòng XML đến. Tôi nghi ngờ rằng có thể lưu một é (hoặc bất kỳ ký tự đặc biệt nào cho vấn đề đó, ngoại trừ các thực thể ký tự được đề cập ở trên) bên trong một tài liệu XML vào trường SQL Server XML, mà không cần thêm DTD hoặc thay thế ký tự đối số tham chiếu thập lục phân của nó. Trong cả hai trường hợp, bạn sẽ cần phải có khả năng sửa đổi XML trước khi nó đi vào cơ sở dữ liệu.

Chỉ cần một ví dụ nhanh cho bất kỳ ai muốn đi xuống tuyến đường "thêm DTD".

Dưới đây là làm thế nào để thêm một DTD nội bộ để một file xml mà tuyên bố một thực thể cho một nhân vật é:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE root [<!ENTITY eacute "&#233;">]> 
<root> 
    <RegionName>Qu&eacute;bec</RegionName> 
</root> 

Nếu bạn đi here và tìm kiếm trên trang "Ctrl + F" cho "eacute", bạn kết thúc trong một danh sách với các ví dụ cho các nhân vật khác mà bạn chỉ có thể sao chép và dán vào DTD nội bộ của riêng bạn.

Sửa

Bạn có thể tắt khóa học thêm tất cả các đơn vị khi chúng được quy định tại các link trên: <!ENTITY eacute "&#233;"><!ENTITY .. // Next entity>, hoặc chỉ cần sao chép tất cả từ file này. Tôi hiểu cách thêm một DTD nội bộ vào mỗi tệp XML mà bạn thêm vào cơ sở dữ liệu không phải là một ý tưởng hay. Tôi sẽ được quan tâm để biết nếu thêm nó cho 1 tập tin sửa chữa vấn đề của bạn mặc dù.

+0

Tôi lo lắng về điều gì sẽ xảy ra khi ký tự đặc biệt tiếp theo xuất hiện theo số –

+0

Tôi đã chỉnh sửa câu trả lời để giải quyết nhận xét của bạn, nó không thực sự là giải pháp, nhưng tôi tự hỏi nếu bất kỳ điều này cho phép bạn chèn XML với các ký tự đặc biệt. –

+0

Giải pháp của bạn giải quyết được câu hỏi đã được hỏi, nhưng thực sự tôi cần một giải pháp chung –

1

Cố gắng thay đổi điều này:

<RegionName>Québec</RegionName> 

tới:

<RegionName><![CDATA[Québec 
]]></RegionName> 
+1

Tôi không kiểm soát luồng xml đến –

9

Tôi sẽ dải tiêu đề ...

Tôi đang gặp vấn đề tương tự với một điều apostrophe chút buồn cười. Tôi nghĩ rằng vấn đề là do thời gian chuỗi là nhận được chuyển đổi sang XML, nó không phải là UTF-8 nữa, nhưng máy chủ sql đang cố gắng sử dụng tiêu đề để giải mã nó. Nếu đó là VARCHAR, nó nằm trong bảng mã của khách hàng. Nếu đó là NVARCHAR, đó là UTF-16. Dưới đây là một số biến thể tôi thử nghiệm:

SQL (varchar, UTF-8):

SELECT CONVERT(XML,'<?xml version="1.0" encoding="UTF-8"?><t>We’re sorry</t>') 

Lỗi:

XML parsing: line 1, character 44, illegal xml character 

SQL (nvarchar, UTF-8):

SELECT CONVERT(XML,N'<?xml version="1.0" encoding="UTF-8"?><t>We’re sorry</t>') 

Lỗi: Phân tích cú pháp XML: dòng 1, ký tự 38, không thể chuyển đổi mã hóa

SQL (varchar, UTF-16)

SELECT CONVERT(XML,'<?xml version="1.0" encoding="UTF-16"?><t>We’re sorry</t>') 

Lỗi:

XML parsing: line 1, character 39, unable to switch the encoding 

SQL (nvarchar, UTF-16)

SELECT CONVERT(XML,N'<?xml version="1.0" encoding="UTF-16"?><t>We’re sorry</t>') 

Làm việc!

+0

Cũng hoạt động! Cảm ơn các giải pháp. –

+0

Do quy trình thực thi, chúng tôi đã sử dụng nguyên tắc câu trả lời của bạn và thay thế tiêu đề sau khi nhận nó dưới dạng varchar (tối đa) như thế này @webtemp = REPLACE (@webtemp, ' ',' '). Nó có thể cần may tất nhiên. Điều này làm việc. –