2013-07-24 3 views
1

유효성을 검사하는 XSD 스키마가있는 XML 파일을 SQL로 가져옵니다. 내가 발견 한 "문제"는 파일의 일부 데이터가 CDATA 태그 안에 포함되어 있지만 해당 XML 요소는 xsd : token으로 정의됩니다 (W3Schools - "토큰 데이터 유형에도 문자가 포함되어 있지만 XML 프로세서는 줄 바꿈, 캐리지 리턴, 탭, 앞뒤 공백 및 여러 공백을 제거합니다. "). 필자가 주목 한 사실은 Typed XML 변수에 대해 SQL에서 간단한 XQuery를 실행했을 때 CDATA 값에 여러 공백을 제거하는 xsd : token 규칙을 적용하고 있다는 것입니다. 파일 공급 업체로 돌아 가기 전에 올바른 결과가 무엇인지 다시 한 번 확인하고 싶었습니다. 당신이 볼 수있는 비 형식화 된 XML 변수를 사용하여, ... ... 결과는 ... ... 코드 조각 아래XML Parser가 CDATA에 XSD 스키마 제한을 적용해야합니까?

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

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 

를 참조에서 공간을 보존 CDATA 텍스트이지만 형식화 된 변수 (xsd : token을 사용)를 사용하면이를 제거합니다. 그런 일이 벌어지면, xsd는 비 CDATA 값에만 적용된 것이라고 생각했습니다. 공백은 우리가로드하는 데이터에 의미를 가지므로 올바른 동작이면 공급 업체와 함께 제기해야합니다. 나는 C#을 통해 데이터를 읽으려고 시도하고 비교로 주어진 결과에 스키마를 적용했지만 제한적인 기술은 그렇게 많은 성공을 거두지 못했습니다.

많은 감사!

답변

1

이 말이 맞습니다. 첫 번째 인스턴스에서 XML은 원시 데이터입니다. 원시 데이터를 선택하면 원시 데이터가 생성됩니다. 데이터에는 공백을 포함하는 공백이 포함됩니다. 두 번째에서는 데이터가 명시 적으로 데이터를 정규화하는 유형, 즉 xsd:token 유형의 의미로 선언됩니다 (공백이 축소되고 앞뒤 공백이 제거됨).

xsd:token 유형은 대부분의 프로그래밍 언어에서 기호 선언과 유사합니다. 그것은 보통 문제 자바/C/C에서 예를 들어, 이름 사이 또는 이름과 과제 사이에 넣어 얼마나 많은 공간을하지 않는 ++이 모든 유효한 : CDATA는 그냥 방법입니다 :

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

CDATA에 관해서 문자를 원시 데이터로 처리하도록 XML 구문 분석기에 지시하지만 다른 정보/지시 사항은 계속 적용됩니다. 따라서 문자 <&을 XML 노드에 삽입하는보다 편리한 방법입니다. 그러나 데이터의 의미와 해석은 변하지 않습니다. 의미 & 데이터의 해석은 스키마에 의해 정의되고 CDATA은 데이터 (스키마에 따라 해석 됨)입니다.

+0

답장을 보내 주셔서 감사합니다. 우리가 문제의 필드에서 XML 파일에 참여해야하는 "기본 키"값 목록이있는 다른 파일 (csv)을 받기 때문에 공급자에게 돌아갈 것입니다. 문제는 csv 파일에 xml 파일에 의해로드 된 값 (스키마가 적용된 값)에 연결되지 않는 경우에 이중 공간을 포함하기 때문에이 공간이 단지 1 공간으로 바뀌어 이제는 고아가 된 데이터를 얻습니다. – user2614273

관련 문제