2012-12-30 4 views
5

XML 파일이있어서이 파일을 XQuery로 변환해야합니다. XML의 간단한 설정을 고려XQuery를 사용하여 XML에서 CSV로 변환

books[book] 
book[@isbn, title, descrption] 

예 :

<books> 
    <book isbn="1590593049"> 
     <title>Extending Flash MX 2004</title> 
     <description> 
     Using javascript alongwith actionscript 3.0 and mxml.</description> 
    </book> 
    <book isbn="0132149184"> 
     <title>Java Software Solutions</title> 
     <description> 
      Complete book full of case studies on business solutions and design concepts while building mission critical 
      business applications. 
     </description> 
    </book> 

방법이 XQuery를 사용하여 CSV 형식으로 변환하는? CSV는 Microsoft Excel에서 사용되며

이므로 쉼표 (,)로 구분되며 특수 문자는 이스케이프되어야합니다.

답변

4

순수의 XPath 2.0 식 :

for $b in /*/book 
    return 
     concat(escape-html-uri(string-join(($b/@isbn, 
              $b/title, 
              $b/description 
             ) 
              /normalize-space(), 
             ",") 
          ), 
      codepoints-to-string(10)) 

XSLT 2 - 대조 :

이 변환이 제공된 XML 문서에인가
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:sequence select= 
    "for $b in /*/book 
     return 
     concat(escape-html-uri(string-join(($b/@isbn, 
              $b/title, 
              $b/description 
              ) 
               /normalize-space(), 
              ',') 
           ), 
       codepoints-to-string(10))"/> 
</xsl:template> 
</xsl:stylesheet> 

(상기 보정 그 부정형) :

,210

이 원하는 정확한 결과는 생성됩니다

1590593049,Extending Flash MX 2004,Using javascript alongwith actionscript 3.0 and mxml. 
0132149184,Java Software Solutions,Complete book full of case studies on business solutions and design concepts while building mission critical business applications. 

업데이트 : 코멘트에

영업 이익은 어떤이 텍스트에서 인용하고 (에 둘러싸여 쉼표 것을 요청했다 그 이후에 어떤 인용 부호가 두 개의 인용 부호로 바뀌고 마지막으로 결과에 인용 부호가 들어 있다면 (따옴표로 묶여 야합니다). 여기

이 생산하는 순수의 XPath 2.0 식입니다이 XPath 표현식은 XML 문서 (새로운 테스트 케이스로 확장)이에 대해 평가

for $b in /*/book, 
    $q in codepoints-to-string(34), 
    $NL in codepoints-to-string(10), 
    $isbn in normalize-space(replace($b/@isbn, ',', concat($q,',',$q))), 
    $t in normalize-space(replace($b/title, ',', concat($q,',',$q))), 
    $d in normalize-space(replace($b/description, ',', concat($q,',',$q))), 
    $res in 
    escape-html-uri(string-join(($isbn,$t,$d), ',')), 
    $res2 in replace($res, $q, concat($q,$q)) 
    return 
    if(contains($res2, $q)) 
     then concat($q, $res2, $q, $NL) 
     else concat($res2, $NL) 

:

<books> 
    <book isbn="1590593049"> 
     <title>Extending Flash MX 2004</title> 
     <description> 
     Using javascript alongwith actionscript 3.0 and mxml.</description> 
    </book> 
    <book isbn="0132149184"> 
     <title>Java Software Solutions</title> 
     <description> 
      Complete book full of case studies on business solutions and design concepts while building mission critical 
      business applications. 
     </description> 
    </book> 
    <book isbn="XX1234567"> 
     <title>Quotes and comma</title> 
     <description> 
      Hello, World from "Ms-Excel" 
     </description> 
    </book> 
</books> 

올바른 결과가 생성됩니다.

1590593049,Extending Flash MX 2004,Using javascript alongwith actionscript 3.0 and mxml. 
0132149184,Java Software Solutions,Complete book full of case studies on business solutions and design concepts while building mission critical business applications. 
"XX1234567,Quotes and comma,Hello"","" World from ""Ms-Excel""" 
+0

하지만 순수한 XPath 2 인 경우 줄 바꿈으로 ' '을 해석하지 않습니다 – BeniBela

+0

@BeniBela, 질문이 명확하지 않습니다. 동일한 XPath 표현식을 사용하는 XSLT 변환. 합법적 인 XPath 표현식이 아닌 경우 오류가 발생하지만 변환은 아무런 문제없이 작동합니다. –

+0

XSLT에 포함 시키면 더 이상 순수 * XPath가 아닙니다. 그런 다음 XML 구문 분석기가 & # xa를 대체합니다. XSLT없이 * pure * XPath를 실행하면 '1590593049, Flash MX 2004 확장, javascript와 함께 actionscript 3.0 및 mxml 사용. 0132149184, Java Software Solutions, 비즈니스 솔루션 및 디자인 개념에 대한 사례 연구가 가득한 책으로 비즈니스 핵심 응용 프로그램을 작성하십시오. '예 : – BeniBela

4

당신의 XML을 가정하면이 사용하여 새 줄에 각 책 노드와 CSV 파일을 만들 수 있습니다 $books 변수에 있습니다

declare function local:my-replace($input) { 
    for $i in $input 
    return '"' || replace($i, '"', '""') || '"' 
}; 
for $book in $books//book 
return string-join(local:my-replace(($book/@isbn, $book/title, $book/description)), ",") || '&#xa;' 

string-join이 다른 문자열 my-replace가의 값을 대체하는 지역의 기능을 연결 귀하의 사양에 따라 시퀀스.

+0

게시 한 스 니펫은 정상적으로 작동하지만 CSV에서는 쉼표 (,)로 구분됩니다. 이제 텍스트 자체에 쉼표가 있으면 excel은 해당 쉼표가 텍스트의 일부일 때 (예 : 설명 셀 또는 제목 셀의 일부) 쉼표를 구분 기호 쉼표로 해석합니다. 일반적인 접근법은 큰 따옴표를 감싸기 위해 쉼표를 이스케이프 처리하고 큰 따옴표 앞에 큰 따옴표를 추가하여 큰 따옴표를 이스케이프 처리하는 것입니다. 안녕하세요, "Ms-Excel"의 World는 다음과 같습니다. "Hello, World from" "Ms -Excel "" "어떻게 이런 식으로 도망 갈 수 있습니까? 큰 도움을 주셔서 감사합니다 –

+0

방금 ​​추가 한 사양을 반영하도록 내 대답을 편집했습니다. 사용자 정의 함수 my-replace를 만들었습니다. 그리고 모든 요소의 끝을 대체하고 "with"로 바꿉니다. – dirkk

관련 문제