2014-12-22 8 views
1

Я пытаюсь отобразить значение узла для имени студента, но оно отображает имя узла и значение в новой строке. Я что-то пропустил?Добавить новый узел/столбец в 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 
+0

Почему Том Райли запись обертка 'Student', в то время как все остальные' StudentID'? И почему у каждого ученика есть другое имя элемента? Вы уверены, что так организован настоящий документ? –

+0

@ michael.hor257k обновленная запись обертки для «Студента» для всех. Идентификаторы учащихся имеют различный тип, поэтому у них разные имена элементов. Я показываю идентификатор типа как столбец, потому что он может иметь разные типы идентификаторов. – user793468

+0

Теперь, когда вы отредактировали вопрос, уже не так, что таблица стилей, отображаемая вами, дает результат, который вы показываете. –

ответ

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> 
+0

Мой плохой! Я не заметил, что у меня был StudentID в качестве первой колонки. Это Student Grade, и это переменная в шаблоне – user793468

+1

Ну, это легко исправить (и вам не нужна переменная). –

2

Имея шаблон, соответствующий StudentID является правильным, но затем, имя студента на самом деле не в @Value, так что следующая переменная из исходного кода не имеет особого смысла:

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

Вместо этого, имя учащегося находится внутри элемента SHNAME. Кроме того, нет необходимости в том, чтобы xsl:for-each прокручивал дочерние элементы StudentID - просто покончите с этим.

Поскольку вы, очевидно, не можете быть уверены, имеет ли StudentID элемента ребенок STDUID или STDSID, использовать выражение XPath, которое отражает это:

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

в качестве последней ноты, я не уверен, если это имеет много смысла чтобы идентификатор студента отображался как в первой, так и в последней ячейке строки. Это поведение вам нужно?

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 Output

Обратите внимание, что вывод 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> 

Вынесено Output (Firefox, теперь обновлен)

enter image description here

+1

'* [start-with (local-name(), 'STD')]/local-name()' is not XPath 1.0. – JLRishe

+0

@JLRishe Вы правы, спасибо за указание! Я случайно тестировал саксон 9.5. Я внесла поправки в свой ответ. –

+0

@ MathiasMüller Мой плохой! Я не заметил, что у меня был StudentID в качестве первой колонки. Это Student Grade, и это переменная в шаблоне – user793468