2013-07-24 2 views
1

Я импортирую некоторые XML-файлы в SQL, которые имеют XSD-схему, с которой я проверяю. «Проблема», которую я обнаружил, заключается в том, что некоторые данные в файлах содержатся в тегах CDATA, но соответствующий элемент XML определяется как токен xsd: (из W3Schools - «Тип данных токена также содержит символы, но XML процессор удалит линейные каналы, возврат каретки, вкладки, начальные и конечные пробелы и несколько пробелов. "). Я заметил, что когда я запускал простой XQuery в SQL против типизированной переменной XML, он применял правила xsd: token для удаления нескольких пробелов для значений CDATA. Прежде чем я вернусь к поставщику файла, я просто хотел бы проверить, какой должен быть правильный результат. Ниже фрагмент кода ...Должен ли XML Parser применять ограничения XSD-схемы для CDATA?

CREATE XML SCHEMA COLLECTION dbo.MyTestSchema 

AS 

N' 
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <xsd:element name="ROOT"> 
    <xsd:complexType> 
     <xsd:complexContent> 
     <xsd:restriction base="xsd:anyType"> 
      <xsd:sequence> 
      <xsd:element ref="Test" 
       minOccurs="0" maxOccurs="unbounded"/> 
      </xsd:sequence> 
     </xsd:restriction> 
     </xsd:complexContent> 
    </xsd:complexType> 
    </xsd:element> 
    <xsd:element name="Test" type="TestType"/> 
    <xsd:simpleType name="TestType"> 
    <xsd:restriction base="xsd:token"> 
    </xsd:restriction> 
    </xsd:simpleType> 
</xsd:schema>' 

GO 

DECLARE @XMLData varchar(MAX) = 
'<ROOT> 
    <Test><![CDATA[0spaces]]></Test> 
    <Test><![CDATA[1 space]]></Test> 
    <Test><![CDATA[2 spaces]]></Test> 
    <Test><![CDATA[3 spaces]]></Test> 
</ROOT>' 

DECLARE @XML xml = @XMLData 
DECLARE @MyTestXML xml(CONTENT dbo.MyTestSchema) = @XMLData 

;WITH WithoutSchema AS 
(
    SELECT [Test] = NULLIF(T2.n.value('.', 'varchar(10)'), '') 
    FROM @XML.nodes('/ROOT') AS T1(n) 
    CROSS APPLY T1.n.nodes('Test') AS T2(n) 
), 
WithSchema AS 
(
    SELECT [Test] = NULLIF(T2.n.value('.', 'varchar(10)'), '') 
    FROM @MyTestXML.nodes('/ROOT') AS T1(n) 
    CROSS APPLY T1.n.nodes('Test') AS T2(n) 
) 
SELECT [WithoutSchema] = N.Test, [WithSchema] = Y.Test 
FROM WithoutSchema N 
INNER JOIN WithSchema Y 
    ON REPLACE(N.Test, ' ', '') = REPLACE(Y.Test, ' ', '') 

GO 

DROP XML SCHEMA COLLECTION dbo.MyTestSchema 

GO 

... результаты ...

WithoutSchema WithSchema 
------------- ---------- 
0spaces  0spaces 
1 space  1 space 
2 spaces  2 spaces 
3 spaces 3 spaces 

... как вы можете видеть, используя не-набран переменной XML сохраняет пробелы в текст CDATA, но с использованием типизированной переменной (которая использует xsd: токен) лишает их. Должно ли это происходить, я думал, что xsd применяется только к значениям, отличным от CDATA? Пространства имеют смысл в данных, которые мы загружаем, поэтому, если это правильное поведение, я должен поднять с поставщиком. Я попытался прочитать данные с помощью C# и применить схему к тем результатам, которые дали в качестве сравнения, но мои навыки там ограничены, поэтому у них не было большого успеха.

Большое спасибо!

ответ

1

Это кажется правильным. В первом случае XML - это просто необработанные данные. Вы выбираете необработанные данные, вы получаете необработанные данные. Ваши данные содержат пробелы, в которые вы получаете пробелы. Во втором вы указываете, что ваши данные имеют тип, который явно нормализует данные, то есть значение типа xsd:token (пробелы сбрасываются, удаляются пробелы ведущие и конечные).

Тип xsd:token аналогичен обозначению символа на большинстве языков программирования. Обычно это не имеет значения, сколько пространства вы поставите между типом и именем или между именем и назначением, например, в Java/C/C++ все это действует:

int   a = 5; // variable is called 'a' not '  a'. 
int b 
= 5; // not very readable, but the variable is called 'b'. 

Что касается CDATA: CDATA это просто способ инструктируйте синтаксический анализатор XML обрабатывать символы как необработанные данные, но любая другая информация/инструкции все еще применяются. Таким образом, это более удобный способ вставки символов < и & в узел XML; однако смысл и, следовательно, интерпретация данных не изменяется. Значение & интерпретация данных определяется схемой, а CDATA - это только данные (которые интерпретируются в соответствии с схемой).

+0

Спасибо за ваш ответ. Я вернусь к нашему поставщику, потому что мы получаем еще один файл (csv) со списком значений «первичного ключа», которые мы должны присоединиться к нашим файлам XML в соответствующем поле. Проблема в том, что в некоторых случаях файл csv содержит двойные пробелы, которые затем не ссылаются на значение, загруженное XML-файлом (с применением их схемы), которое превратилось в одно пространство, так что теперь мы получаем потерянные данные :) – user2614273

Смежные вопросы