将新节点/列添加到xml / xslt

时间:2014-12-22 21:11:42

标签: xml xslt

我正在尝试显示学生姓名的节点值,但它在新行中显示节点名称和值。我在这里错过了什么吗?

这是我的XML:

<StudentRequest Template="StudentRequestResultTabular.xslt" Description="Student Lookup">
  <Student Type="Grade" Value="Freshmen1">
    <STDUID>171TR</STDUID>
    <SHNAME>Tom Riley</SHNAME>
  </Student>
  <Student Type="Grade" Value="Freshmen2">
    <STDUID>164SR</STDUID>
    <SHNAME>Sean Ryan</SHNAME>
  </Student>
  <Student Type="Grade" Value="Sophomore1">
    <STDSID>210JM</STDSID>
    <SHNAME>July Middleton</SHNAME>
  </Student>
  <Student Type="Grade" Value="Senior1">
    <STDSID>252JD</STDSID>
    <SHNAME>Jack Deer</SHNAME>
  </Student>
  <Student Type="Grade" Value="Junior1">
    <STDRID>350JB</STDRID>
    <SHNAME>John Barb</SHNAME>
  </Student>
</StudentRequest>

这是我的XSLT:

<?xml version="1.0" encoding="utf-8"?>
<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="html" indent="yes"/>
  <xsl:template match="/">
    <xsl:apply-templates select="StudentRequest" />
  </xsl:template>

  <xsl:template match="StudentRequest">
    <table>
      <tr>
        <th>Student Grade</th>
        <th>Student Name</th>
        <th>ID Type</th>
        <th>Value</th>
      </tr>
      <xsl:apply-templates select="Student" />
    </table>
  </xsl:template>

  <xsl:template match="Student">
    <xsl:variable name="StudentGrade">
      <xsl:value-of select="@Value"/>
    </xsl:variable>

    <xsl:for-each select="*">     
      <tr>
        <td><xsl:value-of select="$StudentGrade"/></td>
        <td><xsl:value-of select="StudentRequest/Student/SHNAME"/></td>
        <td><xsl:value-of select="local-name()"/></td>
        <td><xsl:value-of select="."/></td>
      </tr>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

当前输出:

StudentGrade Student Name  ID Type  Value 
  Freshmen1                STDUID   171TR
  Freshmen1                SHNAME   Tom Riley
  Freshmen2                STDUID   164SR
  Freshmen2                SHNAME   Sean Ryan
  Sophomore1               STDSID   210JM
  Sophomore1               SHNAME   July Smith
  Senior1                  STDSID   252JD
  Senior1                  SHNAME   Jack Deer
  Junior1                  STDRID   350JB
  Junior1                  SHNAME   John Barb

必需的输出:

StudentGrade  Student Name  ID Type  Value 
  Freshmen1   Tom Riley     STDUID   171TR
  Freshmen2   Sean Ryan     STDUID   164SR
  Sophomore1  July Smith    STDSID   210JM
  Senior1     Jack Deer     STDSID   252JD
  Junior1     John Barb     STDRID   350JB

2 个答案:

答案 0 :(得分:2)

拥有一个匹配StudentID的模板是正确的,但是,学生的名字实际上不在@Value中,因此原始代码中的以下变量没有多大意义:

<xsl:variable name="StudentName">
  <xsl:value-of select="@Value"/>
</xsl:variable>

相反,学生的名字在SHNAME元素内。此外,xsl:for-each无需循环StudentID的子元素 - 只需取消它。

由于您显然无法确定StudentID元素是否包含子STDUIDSTDSID,因此请使用反映此内容的XPath表达式:

<xsl:value-of select="*[starts-with(local-name(),'STD')]"/>

作为最后一点,我不确定学生ID是否出现在一行的第一个和最后一个单元格中是否有意义。这是你需要的行为吗?

XSLT 1.0样式表

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="html" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="StudentRequest">
    <table>
      <tr>
        <th>Student Grade</th>
        <th>Student Name</th>
        <th>ID Type</th>
        <th>Value</th>
      </tr>
      <xsl:apply-templates/>
    </table>
  </xsl:template>

  <xsl:template match="StudentID|Student">
      <tr>
        <td><xsl:value-of select="@Value"/></td>
        <td><xsl:value-of select="SHNAME"/></td>
        <td><xsl:value-of select="local-name(*[starts-with(local-name(),'STD')])"/></td>
        <td><xsl:value-of select="*[starts-with(local-name(),'STD')]"/></td>
      </tr>
  </xsl:template>

</xsl:stylesheet>

HTML输出

请注意,HTML输出不是完整的HTML文档,只是片段。

<table>
   <tr>
      <th>Student Grade</th>
      <th>Student Name</th>
      <th>ID Type</th>
      <th>Value</th>
   </tr>
   <tr>
      <td>Freshmen</td>
      <td>Tom Riley</td>
      <td>STDUID</td>
      <td>171TR</td>
   </tr>
   <tr>
      <td>Freshmen</td>
      <td>Sean Ryan</td>
      <td>STDUID</td>
      <td>164SR</td>
   </tr>
   <tr>
      <td>Sophomore</td>
      <td>July Middleton</td>
      <td>STDSID</td>
      <td>210JM</td>
   </tr>
   <tr>
      <td>Senior</td>
      <td>Jack Deer</td>
      <td>STDSID</td>
      <td>252JD</td>
   </tr>
   <tr>
      <td>Junior</td>
      <td>John Barb</td>
      <td>STDRID</td>
      <td>350JB</td>
   </tr>
</table>

渲染输出(Firefox,现已更新)

  

enter image description here

答案 1 :(得分:1)

我会这样做:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:template match="/">
    <table>
        <tr>
            <th>StudentGrade</th>
            <th>Student Name</th>
            <th>ID Type</th>
            <th>Value</th>
        </tr>
        <xsl:apply-templates select="StudentRequest/Student" />
    </table>
</xsl:template>

<xsl:template match="Student">
    <tr>
        <td><xsl:value-of select="@Value"/></td>
        <td><xsl:value-of select="SHNAME"/></td>
        <td><xsl:value-of select="local-name(*[1])"/></td>
        <td><xsl:value-of select="*[1]"/></td>
    </tr>
</xsl:template>

</xsl:stylesheet>

或者(最好),如果您知道ID类型的所有可能变体,请使用:

<xsl:template match="Student">
    <tr>
        <td><xsl:value-of select="@Value"/></td>
        <td><xsl:value-of select="SHNAME"/></td>
        <td><xsl:value-of select="local-name(STDUID | STDSID | STDRID)"/></td>
        <td><xsl:value-of select="STDUID | STDSID | STDRID"/></td>
    </tr>
</xsl:template>