【问题标题】:Outputting multiple tables in XSLT at once一次在 XSLT 中输出多个表
【发布时间】:2013-01-30 14:16:30
【问题描述】:

我有一个 XML 文档:

<Gym>

<Trainee>
    <Trainee_ID>1521</Trainee_ID>
    <Trainee_Name>Mary Andersen</Trainee_Name>
    <Trainee_Age>23</Trainee_Age>
</Trainee>

<Trainee>
    <Trainee_ID>1522</Trainee_ID>
    <Trainee_Name>Jane Sellers</Trainee_Name>
    <Trainee_Age>56</Trainee_Age>
</Trainee>

<Trainee>
    <Trainee_ID>1523</Trainee_ID>
    <Trainee_Name>Julie Aniston</Trainee_Name>
    <Trainee_Age>32</Trainee_Age>
</Trainee>

<Class>
    <Trainee_ID>1521</Trainee_ID>
    <Course_ID>A21</Course_ID>
    <Class_Room>A1</Class_Room>
</Class>

<Class>
    <Trainee_ID>1522</Trainee_ID>
    <Course_ID>A22</Course_ID>
    <Class_Room>B2</Class_Room>
</Class>

<Class>
    <Trainee_ID>1523</Trainee_ID>
    <Course_ID>B24</Course_ID>
    <Class_Room>B3</Class_Room>
</Class>

<Course>
    <Course_ID>A21</Course_ID>
    <Course_Title>Yoga</Course_Title>
    <Course_Hours_Per_Week>2</Course_Hours_Per_Week>
</Course>

<Course>
    <Course_ID>A22</Course_ID>
    <Course_Title>Pilates</Course_Title>
    <Course_Hours_Per_Week>2</Course_Hours_Per_Week>
</Course>

<Course>
    <Course_ID>B24</Course_ID>
    <Course_Title>Aerobic</Course_Title>
    <Course_Hours_Per_Week>3</Course_Hours_Per_Week>
</Course>

</Gym>

我想要做的是用 XSL 制作 3 个表,标题是子元素的名称(仅一次),子标题是孙元素的名称(仅一次),其余的行和列将被填充具有孙元素的值。

据我所知:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/Gym">
    <html>
    <body>
        <xsl:for-each select="*">
            <table border="1">
            <tr>
            <xsl:if test="position()='1' or position()='4' or position()='7'">
            <xsl:value-of select="translate(name(.), 'abcdefghijklnmopqrstuvwxyz', 'ABCDEFGHIJKLNMOPQRSTUVWXYZ')"/>     
            </xsl:if>
            </tr>
            <tr>
            <xsl:if test="position()='1' or position()='4' or position()='7'">
                <xsl:for-each select="*">
                <th><xsl:value-of select="name(.)"/></th>
                </xsl:for-each>
            </xsl:if>
            </tr>
            <tr>        
            <xsl:for-each select="*">   
                <th>            
                <xsl:value-of select="."/>
                </th>
            </xsl:for-each>
            </tr>
            </table>
            <p></p>
        </xsl:for-each>
    </body>
    </html>
</xsl:template>
</xsl:stylesheet>

这是输出:


(来源:UploadScreenshot.com

发生的情况是,每次为每个子元素创建一个新表时,但我想要的是一个智能代码,它将自动生成所有 3 个表,然后生成标题和子标题,然后它会输入数据。 我想要的是这样的(忽略颜色和文本格式):

我希望我的 XSLT 代码为每个元素实例创建一个表,然后将元素的名称作为标题,然后将子元素作为标题一次,然后用数据填充表。

【问题讨论】:

    标签: xml xslt foreach xslt-grouping xmltable


    【解决方案1】:

    这里使用的方法是使用 Muenchian 分组和键来查找不同的组及其成员。我相信这应该可行:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
      <xsl:key name="kCategory" match="/*/*" use="local-name()"/>
    
      <xsl:template match="/*">
        <div>
          <xsl:apply-templates 
            select="*[generate-id() = generate-id(key('kCategory', local-name())[1])]" />
        </div>
        </xsl:template>
    
      <xsl:template match="/*/*">
        <table>
          <tr class="table-header odd-row">
            <th colspan="3">
              <xsl:value-of select="local-name()"/>
            </th>
          </tr>
          <tr class="column-headers">
            <xsl:apply-templates select="*" mode="colHeader" />
          </tr>
          <xsl:apply-templates select="key('kCategory', local-name())" mode="row"/>
        </table>
      </xsl:template>
    
      <xsl:template match="/*/*/*" mode="colHeader">
        <td>
          <xsl:value-of select="local-name()"/>
        </td>
      </xsl:template>
    
      <xsl:template match="/*/*" mode="row">
        <tr>
          <xsl:if test="position() mod 2 = 1">
            <xsl:attribute name="class">odd-row</xsl:attribute>
          </xsl:if>
          <xsl:apply-templates select="*" mode="value" />
        </tr>
      </xsl:template>
    
      <xsl:template match="/*/*/*" mode="value">
        <td>
          <xsl:value-of select="." />
        </td>
      </xsl:template>
    </xsl:stylesheet>
    

    在您的示例输入上运行时,会产生:

    <div>
      <table>
        <tr class="table-header odd-row">
          <th colspan="3">Trainee</th>
        </tr>
        <tr class="column-headers">
          <td>Trainee_ID</td>
          <td>Trainee_Name</td>
          <td>Trainee_Age</td>
        </tr>
        <tr class="odd-row">
          <td>1521</td>
          <td>Mary Andersen</td>
          <td>23</td>
        </tr>
        <tr>
          <td>1522</td>
          <td>Jane Sellers</td>
          <td>56</td>
        </tr>
        <tr class="odd-row">
          <td>1523</td>
          <td>Julie Aniston</td>
          <td>32</td>
        </tr>
      </table>
      <table>
        <tr class="table-header odd-row">
          <th colspan="3">Class</th>
        </tr>
        <tr class="column-headers">
          <td>Trainee_ID</td>
          <td>Course_ID</td>
          <td>Class_Room</td>
        </tr>
        <tr class="odd-row">
          <td>1521</td>
          <td>A21</td>
          <td>A1</td>
        </tr>
        <tr>
          <td>1522</td>
          <td>A22</td>
          <td>B2</td>
        </tr>
        <tr class="odd-row">
          <td>1523</td>
          <td>B24</td>
          <td>B3</td>
        </tr>
      </table>
      <table>
        <tr class="table-header odd-row">
          <th colspan="3">Course</th>
        </tr>
        <tr class="column-headers">
          <td>Course_ID</td>
          <td>Course_Title</td>
          <td>Course_Hours_Per_Week</td>
        </tr>
        <tr class="odd-row">
          <td>A21</td>
          <td>Yoga</td>
          <td>2</td>
        </tr>
        <tr>
          <td>A22</td>
          <td>Pilates</td>
          <td>2</td>
        </tr>
        <tr class="odd-row">
          <td>B24</td>
          <td>Aerobic</td>
          <td>3</td>
        </tr>
      </table>
    </div>
    

    我想你可以处理颜色和样式?我在我认为合适的地方添加了两个 class 属性。

    您应该能够使用如下 CSS 来获得您需要的样式(它肯定需要一些调整才能使其恰到好处,但这是一般的想法:

    th, td
    {
        border: 2px solid #9BBA58;
        background-color: #E6EDD4;
    }
    
    tr.table-header th, tr.column-headers td
    {
        font-weight: bold;
    }
    
    tr.table-header th
    {
        border-bottom: 4px solid #9BBA58;
    }
    
    tr.odd-row th, tr.odd-row td
    {
        background-color: white;
    }
    

    【讨论】:

    • 我刚试过这个。这真的好像正是我需要的,但由于某种原因,它不work.It输出正是我想要的,但不是作为一个表,它只是输出的一切,而不任何任何像这样的表格式彼此相邻:TraineeTrainee_IDTrainee_NameTrainee_Age1521Mary Andersen231522Jane Sellers561523Julie Aniston32ClassTrainee_IDCourse_IDClass_Room1521A21A11522A22B21523B24B3CourseCourse_IDCourse_TitleCourse_Hours_Per_WeekA21Yoga2A22Pilates2B24Aerobic3
    • 其实我只是把method="xml"改成method="html"就可以了!至于颜色,你能给我一些关于交替行着色的帮助吗?
    • 当然。我已将类添加到奇数行,以便您可以对它们进行不同于非奇数行的样式设置。会这样吗?
    • 是的,这很棒!最后一件事,很抱歉问得太多了,但是我如何设置我想要的特定类的样式,以便添加我需要的粗体文本和颜色以及表格边框颜色?
    • 非常感谢!很遗憾我不能再投票了:P
    猜你喜欢
    • 2019-07-15
    • 2019-01-25
    • 1970-01-01
    • 2010-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-23
    • 2022-01-14
    相关资源
    最近更新 更多