2010-12-17 5 views
1

유닉스에는 여러 xml 파일이 있습니다. 플랫 파일로 변환해야합니다. 그리고 우리는 C 언어를 사용하여 XML 파일의 한 수준을 파싱했습니다. C는 C가 사용 된 Teradata fastload와 inmod를 사용하여 대상 상자와 통신 할 수 있었으며 다른 구문으로는 두 번 파싱을해야했습니다. 하나는 플랫 파일로 변환하기위한 것이고 다른 하나는 ito teradata를로드하기위한 것입니다). 즉Unix XML 파일을 플랫 파일로 변환

<book id="bk101"> 
     <author>Gambardella, Matthew</author> 
     <title>XML Developer's Guide</title> 
     <genre>Computer</genre> 
     <price>44.95</price> 
    </book> 

bk101~Gambardella, Matthew~XML Developer's Guide~Computer~44.95~ 

C.에서 파일을 구문 분석하지만 다음과 같습니다 XML 파일의 원래 형식을 본 후 달성이 우리로 변환되어 아래 파일. (필수 파일로 생각하지 말아주세요.) 그냥 생각하고 있습니다.

<book id="bk101"> 
     <author>Gambardella, Matthew</author> 
     <title>XML Developer's Guide</title> 
     <genre>Computer</genre> 
      <modified>2010-01-02</modified> 
      <modified>2010-01-03</modified> 
     <price>44.95</price> 
    </book> 

이것은 두 개의 레코드로 변환되어야합니다.

bk101~Gambardella, Matthew~XML Developer's Guide~Computer~2010-01-02~44.95~ 
bk101~Gambardella, Matthew~XML Developer's Guide~Computer~2010-01-03~44.95~ 

하지만 지금 우리는 우리 C 코드가이 req를 위해 복잡해질 것이라고 생각합니다. 그래서 우리는 유닉스에서 쉽게 사용할 수있는 다른 옵션을 찾고있다. 아무도 유닉스를위한 다른 언어/옵션의 실제 예제 코드를 제공해 줄 수 있습니까?

답변

3

당신은 XSLT를 사용할 수 있습니다. 나는 Saxon (Java)을 유닉스에서 사용할 수있다.

이 스타일은 XML 샘플을 모두 처리 : 더 modified 요소가없는 경우

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 
    <xsl:template match="/book"> 
    <xsl:choose> 
     <xsl:when test="modified"> 
     <xsl:for-each select="modified"> 
      <xsl:call-template name="dump-line"> 
      <xsl:with-param name="pos" select="position()"/> 
      </xsl:call-template>   
     </xsl:for-each> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:value-of select="@id"/><xsl:text>~</xsl:text> 
     <xsl:value-of select="author"/><xsl:text>~</xsl:text> 
     <xsl:value-of select="title"/><xsl:text>~</xsl:text> 
     <xsl:value-of select="genre"/><xsl:text>~</xsl:text> 
     <xsl:value-of select="price"/> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

    <xsl:template name="dump-line"> 
    <xsl:param name="pos"/> 
    <xsl:value-of select="/book/@id"/><xsl:text>~</xsl:text> 
    <xsl:value-of select="/book/author"/><xsl:text>~</xsl:text> 
    <xsl:value-of select="/book/title"/><xsl:text>~</xsl:text> 
    <xsl:value-of select="/book/genre"/><xsl:text>~</xsl:text> 
    <xsl:value-of select="/book/modified[$pos]"/><xsl:text>~</xsl:text> 
    <xsl:value-of select="/book/price"/> 
    <xsl:text>&#x0A;</xsl:text> 
    </xsl:template> 
</xsl:stylesheet> 

, 하나 개의 레코드가 출력됩니다. modified 요소가있는 경우 modified 요소만큼 많은 레코드를 출력합니다.수정 요소/w

샘플 출력 : 당신의 응답을

bk101~Gambardella, Matthew~XML Developer's Guide~Computer~2010-01-02~44.95 
bk101~Gambardella, Matthew~XML Developer's Guide~Computer~2010-01-03~44.95 
+0

대단히 감사합니다. 당신은 훌륭한 실례를 제공했습니다. 고마워. 귀하의 예가 XSLT를 배우기 위해 관심을 모았습니다. 내가 예제 코드를 실행하는 데 xalan (C 버전)을 사용하고 완벽하게 작동합니다. Stackoverflow 괴짜가 훌륭합니다. 모든 도움과 제안을 주신 모든 분들께 감사드립니다. 사용 가능한 옵션을 대부분 시험해보고 최종 제품에 대해 알려줍니다. –

+0

다시 한 번 감사드립니다. 여러 루프를 가지고 훨씬 복잡한 XML 파일을위한 간단한 xslt 스크립트를 만들 수 있습니다. 계속 흔들어 라. 당신 덕분에 이제는 600 줄의 C 코드를 복잡하게 만들고 새로운 언어를 배우기 시작한다는 생각에서 벗어날 수있었습니다. 이제 xalan을 사용하기 위해 조직을 추구 한 후 유닉스에서 동일한 스크립트와 실행을 시도해야한다. –

+0

대단히 반갑습니다. 도움이 된 것을 기쁘게 생각합니다. 당신은 색슨을 정말로보아야한다. HE 버전은 여전히 ​​무료이며 XSLT 2.0을 지원합니다. http://saxon.sourceforge.net/ Xalan이 2.0을 지원하지 않습니다 –

0

회선을 bk101~Gambardella, Matthew~XML Developer's Guide~Computer~2010-01-02,2010-01-03~44.95~으로 성형하는 것은 어떻습니까? 물론 수정 된 필드에 값 목록이 포함될 수 있다는 점을 특별히 고려해야합니다. 그것은 당신이 그것을 만들 수있는만큼 평평합니다.

+0

감사합니다. 글쎄, 궁극적으로 그것은 데이터베이스 테이블에로드해야합니다. 따라서이 기록은보고를 위해 두 개의 기록으로 분리되어야합니다. 우리는 curently perl xml 파서를 생각하고 있습니다. 모든 신체는 위의 요구 사항을 충족시킬 수있는 perl의 예제 코드를 알고 있습니까? –

+0

당신이 구글을 사용한다면 많은 예제가있을 것입니다. 스크립트를 사용해야한다는 요구 사항입니까? 모노는 도구로 받아 들여질 수 있습니까? .NET 프레임 워크는 구문 분석 및 XML 처리와 관련하여 많은 편의를 제공하여 매우 쉬운 작업입니다 ... –

1

데이터를 데이터베이스로로드하고 다른 필드와 다 대일 관계를 공유하는 필드가있는 경우 데이터베이스 구조가 스크래치에 부합하는지 확인해야합니다. 나는. 책 한 권과 수정 일 한 표. 그렇지 않으면 사실 두 개의 수정 날짜가있는 책이 두 권있는 것처럼 보입니다.

그러나 데이터베이스에 데이터를로드하는 경우 왜 처음에 플랫 파일로 변환합니까? 파싱 ​​한 번에 두 번 통과하는 것을 피하고 싶다고 했잖아. XML을 구문 분석하고 플랫 파일로 출력하는 패스 하나와 플랫 파일을 구문 분석하여 데이터베이스에 입력하는 패스가있는 것 같습니다. 단순히 XMl을 구문 분석하고 데이터를 데이터베이스에 직접 저장하지 않는 이유는 무엇입니까?

XML과 같은 형식이 발명되고 텍스트 기반 문서에서 복잡한 데이터 관계를 캡슐화하는 이유가 있습니다. "플랫 파일"로 변환하면 그 복잡성을 잃게됩니다. 그런 복잡성을 처리하고 그러한 관계를 저장할 수있는 환경으로 데이터를 가져 오려면 왜 계속 사용하지 않을까요?

데이터베이스에 API가 있거나 플랫 파일 만 가져올 수 있습니까?

--- 편집 ---

그것은보다 코멘트 일련의 답변의 일환으로 응답하는 것이 더 쉽습니다.

먼저 설명해 주셔서 감사합니다. 둘째, 예제 코드를 제공 할 수 없습니다. 대부분 당신이 원하는 것은 아주 구체적으로 들립니다. 셋째, 두 가지 옵션이 있다고 생각합니다.

1) XML을 파싱하기 위해 이미 작성된 C 코드가 있습니다. Teradata 데이터베이스에 직접 데이터를 가져 오는 비용과 그 이후의 유지 보수 비용을 보완하기 위해 Perl에서 모든 것을 버리고 다시 작성하는 비용을 고려해야합니다.

2) Perl의 경우 XML 파서가 많이 있으며 C에서 사용하는 것보다 훨씬 쉽게 XML 트리/데이터 구조를 탐색합니다. Perl을 좋아하지는 않지만 처리 할 코드를 작성했습니다. C에서 준비된 파싱 된 XML 트리와 나는 결코 그것을 미워하지 않았다. 반대로 Perl을 사용하면 더 간단하고 빠릅니다.

XML을 구문 분석 할 수있는 수많은 펄 모듈이 있습니다. 나는 그들이 가장 쉽게 또는 당신에게 사용하기에 적합한 결정하는 그들에 대한 몇 가지 리뷰에 대한 인터넷을 검색하는 것이 좋습니다.

Teradata :: SQL이라는 Perl 모듈을 사용하면 데이터를 Teradata 데이터베이스로 가져올 수 있습니다. 더 쉽고/더/더 사용하기 쉬운 다른 모듈이있을 수 있습니다. 나는 그 (것)들에있는 아무 경험도 없다 그래서 추천을 할 수 없다. 유용 할 수도있는 모듈을 찾으려면 http://www.cpan.org을 검색하십시오.


마지막으로, Teradata 데이터베이스의 디자인이 데이터 입력과 일치하는지 확인하는 것이 좋습니다. 위에서 언급했듯이 수정 날짜와 책은 다 대일 관계를 가지고 있으므로 수정 날짜에 대한 테이블과 책에 대한 테이블이 필요하며 테이블 디자인에서 다 대일 관계를 수정할 필요가 있음을 의미합니다. 한 줄에 하나의 항목을 넣을 경우 수정 날짜 만 변경된 동일한 책에 대해 여러 행을 작성하는 것은 매우 잘못입니다. 저자와 같이 다른 많은 관계가있을 수 있습니다. 저자 A1과 A2가 M1과 M2로 작성한 책 B를 상상해보십시오. 위에 설명 된 방법을 사용하여 각 조합마다 하나의 행을 사용하면 동일한 책에 대해 4 개의 항목이 생겨 결국 같은 저자이지만 서로 다른 저자가 작성한 2 권의 책이있는 것처럼 보입니다.

XML 파일의 데이터 구조를 이해하는 데 시간을 할애해야합니다. 이것은 DTD에 의해 명확하게 정의되어야한다.

+0

Teradata inmod 기능은 공유 객체 (Windows의 dll이므로 유닉스에서 사용됨)입니다. fastload 유틸리티로 호출하여 레코드를 테라 데이타에로드 할 수 있습니다. 그래서 여기에 내가 현재 xml 파일에 단 하나의 패스를하고있다. Teradata는 XML에 대한 지원이 적고 가까운 시일 내에 업그레이드 이후에만 지원 될 수있는 파쇄 옵션이 있습니다. 그래서 우리는 두 가지 패스가 필요하지만 다른 옵션을 찾고 있습니다. 이 방법으로 변환 할 수있는 perl/some 다른 예제 코드를 제공해 주시겠습니까? 귀하의 회신에 감사드립니다. –

+0

귀하의 의견과 제안에 감사드립니다. –

1

XSLT는 옵션입니다. xsltproc 도구를 확인하십시오.

또는 XQuery를 훨씬 쉽게 만들 수도 있지만 텍스트를 생성하는 데 강요해야 할 수도 있습니다. 다음 XQuery를 스크립트는 (나와 몇 필드를) 원하는 거의 수행합니다

나는 '하지만 당신은 유닉스에 대한 또 다른 인기는 XQuery 프로세서가 XQilla입니다

java net.sf.saxon.Query '!method=text' script.xq 

Saxon 통해 실행할 수 있습니다

for $book in doc("book.xml")/book 
for $mod in $book/modified 
return concat($book/@id, "~", $book/title, "~", $mod, " 
") 

그것은 비 XML 출력을 생성 할 수 있는지 확신하지 못합니다.

은 (줄 바꿈을 생성하는 내 어색한 방식에 스마트 대안이있을 수 있습니다.)

관련 문제