2008-09-17 28 views
6

Phải có một cách tổng quát để chuyển đổi một số XML hierachical như:Flatten XML để bảng HTML

<element1 A="AValue" B="BValue"> 
    <element2 C="DValue" D="CValue"> 
     <element3 E="EValue1" F="FValue1"/> 
     <element3 E="EValue2" F="FValue2"/> 
    </element2> 
    ... 
</element1> 

vào XML phẳng (html) nhặt thuộc tính được lựa chọn trên đường đi và cung cấp các nhãn khác nhau cho các thuộc tính trở thành tiêu đề cột.

<table> 
    <tr> 
    <th>A_Label</th> 
    <th>D_Label</th> 
    <th>E_Label</th> 
    <th>F_Label</th> 
    </tr> 
    <tr> 
    <td>AValue</td> 
    <td>DValue</td> 
    <td>EValue1</td> 
    <td>FValue1</td> 
    </tr> 
    <tr> 
    <td>AValue</td> 
    <td>DValue</td> 
    <td>EValue2</td> 
    <td>FValue2</td> 
    </tr> 
<table> 

OK, vì vậy không có giải pháp chung do ghi nhãn lại thuộc tính nhưng bạn hiểu ý tôi là hy vọng. Tôi vừa mới bắt đầu trên tất cả các công cụ XSLT/XPATH vì vậy tôi sẽ làm việc trong thời gian tốt nhưng bất kỳ manh mối nào cũng hữu ích.

Trả lời

5

Tôi không chắc chắn 100% những gì bạn đang cố gắng làm nhưng giải pháp này có thể hoạt động nếu element1, element2 và element3 của bạn được lồng nhau một cách nhất quán.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/"> 
     <table> 
      <xsl:apply-templates select="//element3"></xsl:apply-templates> 
     </table> 
    </xsl:template> 

    <xsl:template match="element3"> 
     <tr> 
      <td><xsl:value-of select="../../@A"/></td> 
      <td><xsl:value-of select="../../@B"/></td> 
      <td><xsl:value-of select="../@C"/></td> 
      <td><xsl:value-of select="../@D"/></td> 
      <td><xsl:value-of select="@E"/></td> 
      <td><xsl:value-of select="@F"/></td> 
     </tr> 
     <xsl:apply-templates select="*"></xsl:apply-templates> 
    </xsl:template> 

</xsl:stylesheet> 
+0

Cảm ơn Darrel. Hoạt động tuyệt vời. –

+0

Mẫu đẹp. Cảm ơn! – chrismead

0

Chúng tôi đã có một chương trình Pro * C đọc từ một cơ sở dữ liệu Oracle, nó gọi một tập lệnh perl để thực hiện một số Java trích xuất dữ liệu ở định dạng XML từ cơ sở dữ liệu nói trên để gọi một tệp lô để thực thi một số vbscript FTPing tệp cho một số máy chủ khác. Tôi đã thực sự hy vọng cho một cái gì đó ở Fortran.

+0

whew ... cho đến khi tôi đã đến phần fortran Tôi nghĩ bạn đã nghiêm trọng có trong một giây – davr

0

Các câu hỏi ban đầu cần phải được làm rõ:

  • gì xảy ra với BValue và CValue trong câu hỏi ban đầu? Có lý do nào khiến họ không phải là một phần của cấu trúc phẳng không?
  • Tất cả các phần tử trong tài liệu XML có 2 thuộc tính hoặc điều này hoàn toàn tùy ý không?
  • Chỉ có 3 loại phần tử và chúng luôn được lồng nhau như trong ví dụ?
  • Phần tử của bạn có thể được lặp lại chính nó hoặc đây có phải là phần tử gốc của tài liệu của bạn không?

Trong XSLT, bạn có thể viết máy biến áp rất chung chung, nhưng thường dễ dàng hơn để viết biểu định kiểu để chuyển đổi tài liệu khi bạn có thể thực hiện bất kỳ hạn chế nào.

0

Tôi đã sử dụng phiên bản mở rộng của mẫu bên dưới để làm phẳng XML có cấu trúc. Cảnh báo: Đã có một số mã cụ thể trong phiên bản gốc (nó thực sự đã biến XML thành CSV) mà tôi vừa bị loại bỏ và tôi đã không kiểm tra phiên bản này.

Cách cơ bản mà nó hoạt động phải rõ ràng: nó in mọi thứ không có nút con và theo cách khác đệ quy gọi mẫu trên nút() có con. Tôi không nghĩ rằng nó xử lý các thuộc tính và bình luận chính xác như bây giờ, nhưng điều đó không khó để sửa chữa.

<?xml version="1.0" encoding="UTF-8"?> 

<!-- XSL template to flatten structured XML, before converting to CSV. --> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="xml" indent="yes" encoding="UTF-8"/> 

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

    <xsl:template match="/"> 
     <xsl:apply-templates select="//yourElementsToFlatten"/> 
    </xsl:template> 

    <xsl:template match="//yourElementsToFlatten"> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:template> 

    <xsl:template match="@*|node()"> 
     <xsl:choose> 
      <!-- If the element has multiple childs, call this template 
       on its children to flatten it--> 
      <xsl:when test="count(child::*) > 0"> 
       <xsl:apply-templates select="@*|node()"/> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:copy> 
        <xsl:value-of select="text()" /> 
       </xsl:copy> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 

</xsl:stylesheet> 
1

Tôi cần một XSLT tương tự nhưng có chiều sâu không xác định, đây là cách tôi đã làm.

Đầu tiên, thêm một wrapper cho kết quả bảng HTML/def liệt kê và gọi mẫu mode = "nôn" để san bằng cây XML của chúng tôi:

<xsl:element name="div"> 
    <xsl:attribute name="class" select="puke" /> 
    <xsl:apply-templates select="$notice" mode="puke" /> 
</xsl:element> 

Ở đây chúng ta phù hợp với mỗi nút để hiển thị nội dung của nó (ví dụ text()) và các thuộc tính của nó. Chúng tôi làm điều này đệ quy. Tôi đã sử dụng dl/dt/dd vì cây nguồn của tôi là một cây phức tạp mà không thể làm phẳng như a.

<!-- @description: 
    Display all field from the notice so the customer can tell what he want 
--> 
<xsl:template match="node()" mode="puke"> 
<xsl:message> 
    puking : <xsl:value-of select="local-name(.)" /> 
</xsl:message> 
    <xsl:element name="dl"> 
     <xsl:element name="dt"> 
      <xsl:attribute name="class">tagName</xsl:attribute> 
      <xsl:value-of select="local-name(.)" /> 
     </xsl:element> 
     <xsl:element name="dd"> 
      <xsl:attribute name="class">tagText</xsl:attribute> 
      <xsl:value-of select="text()" /></xsl:element> 
     <xsl:element name="dl"> 
      <xsl:attribute name="class">attr</xsl:attribute> 
      <!-- display attribute --> 
      <xsl:apply-templates select="@*" /> 
     </xsl:element> 
    </xsl:element> 
    <!-- recursive call on node() --> 
    <xsl:apply-templates select="./*" mode="puke" />  
</xsl:template> 

Thuộc tính đối sánh của một nút nhất định và hiển thị chúng.

CSS sử dụng trong định dạng HTML kết quả:

<style> 
.puke { 
    background-color: #BDD6DE; 
    clear: both; 
} 
.tagName, .attrName { 
    float: left; 
} 
.tagText, .attrText { 
    clear: right; 
} 
</style>