2010-05-17 39 views
6

Tôi muốn chuyển đổi XML thành CSV sử dụng một XSLT, nhưng khi áp dụng XSL từ thread SO với tựa đề XML To CSV XSLT chống đầu vào của tôi:XML để CSV sử dụng XSLT giúp đỡ

 
<WhoisRecord> 
    <DomainName>127.0.0.1</DomainName> 
    <RegistryData> 
    <AbuseContact> 
     <Email>[email protected]</Email> 
     <Name>Internet Corporation for Assigned Names and Number</Name> 
     <Phone>+1-310-301-5820</Phone> 
    </AbuseContact> 
    <AdministrativeContact i:nil="true"/> 
    <BillingContact i:nil="true"/> 
    <CreatedDate/> 
    <RawText>...</RawText> 
    <Registrant> 
     <Address>4676 Admiralty Way, Suite 330</Address> 
     <City>Marina del Rey</City> 
     <Country>US</Country> 
     <Name>Internet Assigned Numbers Authority</Name> 
     <PostalCode>90292-6695</PostalCode> 
     <StateProv>CA</StateProv> 
    </Registrant> 
    <TechnicalContact> 
     <Email>[email protected]</Email> 
     <Name>Internet Corporation for Assigned Names and Number</Name> 
     <Phone>+1-310-301-5820</Phone> 
    </TechnicalContact> 
    <UpdatedDate>2010-04-14</UpdatedDate> 
    <ZoneContact i:nil="true"/> 
    </RegistryData> 
</WhoisRecord> 

tôi kết thúc với:

[email protected] Corporation for Assigned Names and Number+1-310-301-5820, 
    , 
    , 
    , 
    ...,  
    4676 Admiralty Way, Suite 330Marina del ReyUSInternet Assigned Numbers Authority90292-6695CA,  
    [email protected] Corporation for Assigned Names and Number+1-310-301-5820,  
    2010-04-14, 

Vấn đề của tôi là chuyển đổi kết quả là thiếu các nút (như phần tử DomainName chứa địa chỉ IP) và một số nút con được ghép nối không có dấu phẩy (như con của AbuseContact).

Tôi muốn xem tất cả đầu ra XML ở dạng CSV và các chuỗi như: "[email protected] Corporation for Assigned Names and Number + 1-310-301-5820", được phân tách bằng dấu phẩy.

XSL của tôi khá gỉ. Trợ giúp của bạn được đánh giá cao. :)

Đây là XSL Tôi đang sử dụng:

 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text" encoding="iso-8859-1"/> 

<xsl:strip-space elements="*" /> 

<xsl:template match="/*/child::*"> 
    <xsl:for-each select="child::*"> 
    <xsl:if test="position() != last()"><xsl:value-of select="normalize-space(.)"/>, </xsl:if> 
    <xsl:if test="position() = last()"><xsl:value-of select="normalize-space(.)"/><xsl:text>
</xsl:text> 
    </xsl:if> 
    </xsl:for-each> 
</xsl:template> 

</xsl:stylesheet> 
+1

Câu hỏi hay (+1). Xem câu trả lời của tôi cho một giải pháp đơn giản. :) –

Trả lời

3

chuyển đổi đơn giản này tạo ra kết quả mong muốn:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 
<xsl:strip-space elements="*"/> 

    <xsl:template match="/"> 
    <xsl:apply-templates select="//text()"/> 
    </xsl:template> 

    <xsl:template match="text()"> 
     <xsl:copy-of select="."/> 
     <xsl:if test="not(position()=last())">,</xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

Do lưu ý việc sử dụng:

<xsl:strip-space elements="*"/> 

để loại bỏ bất kỳ nút văn bản trắng-không gian-only.

Cập nhật: AJ nêu ra vấn đề rằng các kết quả sẽ được nhóm thành các phần tử/tuples trên mỗi dòng. Nó không được định nghĩa trong câu hỏi một bản ghi/tuple chính xác là gì. Do đó giải pháp hiện tại giải quyết hai vấn đề của các nút văn bản chỉ trắng-không gian và các dấu phẩy bị thiếu, nhưng không nhằm mục đích dò tìm đầu ra thành các bản ghi/bộ dữ liệu.

+0

CSV không yêu cầu một dòng mới để tách một bộ/bộ hồ sơ? –

+2

Nó không phải là rõ ràng từ câu hỏi những gì tạo thành một tuple hồ sơ - điều này có ý nghĩa trong thế giới DB quan hệ, nhưng đối với một cây cần phải được xác định rõ ràng. Tôi cũng đã chỉnh sửa câu trả lời của tôi để phản ánh nhận xét của bạn. –

+0

Xin cảm ơn các bạn! Tôi muốn một bộ/bộ hồ sơ. Làm thế nào cứng sẽ được? Tôi cũng muốn có thể áp dụng XSL cho các tài liệu XML có cấu trúc tương tự - các giải pháp không tham chiếu các phần tử theo tên được ưu tiên. Cảm ơn một lần nữa. :) –

0

Tôi tin rằng bạn cần giải pháp đệ quy để tiếp cận vấn đề này. Vì vậy, bạn cần một cái gì đó mà giữ lặn vào cây cho đến khi nó đạt đến một nút text(). Nếu nút text() đó thực sự là một nút con của nút cuối cùng, thì nó sẽ đặt một dòng mới. Nếu không, nó chỉ đặt giá trị bằng dấu phẩy.

Nếu nút không có nút văn bản() làm nút con, sau đó đệ quy bắt đầu đào vào cây đó.

<xsl:strip-space elements="*" />  

<xsl:template name="rec">   
    <xsl:param name="node"/>   
    <xsl:for-each select="child::*"> 
     <xsl:choose> 
      <xsl:when test="child::text()"> 
       <xsl:choose>       
        <xsl:when test="local-name(.) != 'UpdatedDate'">"<xsl:value-of select="normalize-space(.)"/>", </xsl:when> 
        <xsl:otherwise>"<xsl:value-of select="normalize-space(.)"/>" <xsl:text>&#xD;</xsl:text></xsl:otherwise> 
       </xsl:choose>      
      </xsl:when> 
      <xsl:when test="child::node()"> 
       <xsl:call-template name="rec"> 
        <xsl:with-param name="node" select="child::node()"/> 
       </xsl:call-template>      
      </xsl:when> 
     </xsl:choose> 

    </xsl:for-each> 
</xsl:template> 

này không đánh lừa bằng chứng, nhưng nó tạo ra kết quả này trên cuối của tôi với Saxon:

"127.0.0.1", "[email protected]", "Internet Corporation for Assigned Names and Number", "+1-310-301-5820", "...", "4676 Admiralty Way, Suite 330", "Marina del Rey", "US", "Internet Assigned Numbers Authority", "90292-6695", "CA", "[email protected]", "Internet Corporation for Assigned Names and Number", "+1-310-301-5820", "2010-04-14" 

Hy vọng điều này sẽ hữu ích.

+0

Tại sao câu trả lời của tôi bị bỏ phiếu? Một bình luận về nó sẽ hữu ích. Tôi mới làm quen với XSLT. –

+1

Có lẽ vì không có đệ quy hoặc vòng lặp rõ ràng cần thiết để di chuyển dọc theo trục con. – Tomalak

Các vấn đề liên quan