2009-12-18 30 views
5

Với XML sau:Thực hiện "Nhóm By" truy vấn trong XPath XSL

<results name="queryResults"> 
    <int name="intfield1:[* TO 10]">11</int> 
    <int name="intfield2:[10 TO 20]">9</int> 
    <int name="intfield1:[10 TO 20]">12</int> 
</results> 

Tôi muốn tạo ra XML này:

<results> 
    <field name="numberfield1"> 
     <value name="[* TO 10]">11</value> 
     <value name="[10 TO 10]">12</value> 
    </field> 
    <field name="numberfield2"> 
     <value name="[10 TO 20]">9</value> 
    </field> 
</results> 

Tôi không thể nghĩ làm thế nào để làm điều này trong XSL chủ yếu là vì tôi muốn Nhóm theo số thứ tự .. Tất cả những gì tôi có thể đưa ra là:

<xsl:if test="count(results/int) &gt; 0"> 
    <results> 
    <xsl:for-each select="results/int"> 
     <field> 
      <xsl:attribute name="name"> 
       <xsl:value-of select="substring-before(@name, ':')"/></xsl:attribute> 
      <value> 
       <xsl:attribute name="name"> 
        <xsl:value-of select="substring-after(@name, ':') "/> 
       </xsl:attribute> 
       <xsl:value-of select="."/> 
      </value> 
     </field> 
    </xsl:for-each> 
    </results> 
</xsl:if> 

Tuy nhiên điều này không tạo ra nhóm tốt đẹp ed danh sách thay vào đó tôi nhận được điều này:

<results> 
    <field name="numberfield1"> 
     <value name="[* TO 10]">11</value> 
    </field> 
    <field name="numberfield2"> 
     <value name="[10 TO 20]">9</value> 
    </field> 
    <field name="numberfield1"> 
     <value name="[10 TO 10]">12</value> 
    </field> 
</results> 

Nếu ai đó có thể khiến tôi đi đúng hướng .. Điều đó sẽ tuyệt vời?

Cảm ơn

Trả lời

11

Để làm điều này trong XSLT 1.0, bạn sẽ phải sử dụng một kỹ thuật gọi là "muenchian grouping". Đầu tiên tạo ra một chìa khóa của các nút mà bạn muốn nhóm

<xsl:key name="intfield" match="int" use="substring-before(@name, ':')" /> 

Tiếp theo, bạn lặp qua tất cả các nút, nhưng chỉ chọn những điều đó xảy ra để là người đầu tiên trong nhóm có liên quan

<xsl:for-each select="int[generate-id() = generate-id(key('intfield', substring-before(@name, ':'))[1])]"> 

Tiếp theo, bạn có thể lặp lại sử dụng phím để lặp qua tất cả các nút trong nhóm

<xsl:variable name="intfieldname" select="substring-before(@name, ':')"/> 
<xsl:for-each select="key('intfield', $intfieldname)"> 

đưa này tất cả cùng nhau mang đến cho

012.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml"/> 
    <xsl:key name="intfield" match="int" use="substring-before(@name, ':')"/> 
    <xsl:template match="/results"> 
     <results> 
     <xsl:for-each select="int[generate-id() = generate-id(key('intfield', substring-before(@name, ':'))[1])]"> 
      <xsl:variable name="intfieldname" select="substring-before(@name, ':')"/> 
      <field> 
       <xsl:attribute name="name"> 
        <xsl:value-of select="$intfieldname"/> 
       </xsl:attribute> 
       <xsl:for-each select="key('intfield', $intfieldname)"> 
        <value> 
        <xsl:attribute name="name"> 
         <xsl:value-of select="substring-after(@name, ':')"/> 
        </xsl:attribute> 
        <xsl:value-of select="."/> 
        </value> 
       </xsl:for-each> 
      </field> 
     </xsl:for-each> 
     </results> 
    </xsl:template> 
</xsl:stylesheet> 

Trong ví dụ của bạn, 'intfield' trở thành 'numberfield' mặc dù. Tôi đã giữ tên như 'intfield' trong ví dụ trên.

  • sửa lỗi chính tả.
+0

Bạn người đàn ông .. cổ vũ .. chỉ cần thử nó và nó hoạt động một điều trị. Tôi sẽ phải tìm kiếm điều này "nhóm meunchian" như tại thời điểm này tất cả có vẻ như voodoo – CraftyFella

+0

Một câu hỏi ... Có cách nào để hạn chế các lĩnh vực int mà nó tạo ra .. như có một danh sách khác của int khác ở đâu và đưa những người đó vào khóa intfield? Hy vọng rằng có ý nghĩa – CraftyFella

+1

Đúng, trong thuộc tính 'match' của xsl: key, bạn có thể nhập bất kỳ biểu thức Xpath đầy đủ nào để chính xác hơn về những nút bạn yêu cầu. Ví dụ:

3

Nhóm Muenchian là một tác phẩm của thiên tài. Không dễ hiểu, nhưng hãy xem: http://www.jenitennison.com/xslt/grouping/muenchian.html

Để đơn giản quá trình W3C hỗ trợ đặc biệt nhóm trong XSLT2.0. Xem, ví dụ: http://www.xml.com/pub/a/2003/11/05/tr.html

Tuy nhiên không phải tất cả các môi trường hỗ trợ XSLT2.0

+0

Sử dụng MS .NET để chỉ XSL 1.0 cho tôi .. bạn là chính xác mặc dù .. nó là một tác phẩm của thiên tài .. Tôi sẽ cung cấp cho liên kết đó một bài đọc. cảm ơn – CraftyFella

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