Как выбрать определенный узел или элемент в XML с преобразованиями XSLT? - PullRequest
2 голосов
/ 20 июля 2010

Мой XML

<row>
  <entry>1.</entry>
  <entry>foo</entry>
  <entry>morefoo</entry>
</row>
<row>
  <entry>2.</entry>
  <entry>2foo</entry>
  <entry>2morefoo</entry>
</row>

с использованием XSLT, я пытаюсь представить эту информацию в HTML-таблице, и я хочу иметь серийный номерcolumn.

Как выбрать значение только для первого тега 'entry'?

Ответы [ 4 ]

2 голосов
/ 20 июля 2010

Мой XML

<row> 
<entry>1.</entry> 
<entry>foo</entry> 
<entry>morefoo</entry> 
</row> 
<row> 
<entry>2.</entry> 
<entry>2foo</entry> 
<entry>2morefoo</entry> 
</row>

Это некорректный XML-документ . Правильно сформированный XML-документ должен иметь ровно один элемент верхнего уровня. Я буду использовать следующий (исправленный, чтобы быть правильно оформленным) документ XML:

<rows>
    <row>
        <entry>1.</entry>
        <entry>foo</entry>
        <entry>morefoo</entry>
    </row>
    <row>
        <entry>2.</entry>
        <entry>2foo</entry>
        <entry>2morefoo</entry>
    </row>
</rows>

Как мне выбрать значение только первого тега 'entry'?

/*/row/entry[1]

Вышеприведенное выбирает первый entry элемент -детей каждого элемента row.

/*/row[1]/entry[1]

Вышеуказанный элемент выбирает первый entry элемент -дет первого элемента row в документе.

/*/row[2]/entry[1]

Вышеуказанный элемент выбирает первый entry элемент -дет второго элемента row в документе.

(//entry)[1]

Вышеуказанный элемент выбирает первый entry элемент во всем документе.

//entry[1]

Обратите внимание, что это отличается от предыдущего выражения: здесь выбирается каждый элемент entry в документе, который является первым entry -компонентом его родителя.

1 голос
/ 20 июля 2010

В вашем XSLT должно быть что-то вроде этого:

<!-- matches the root (not specified in your post) -->
<xsl:template match="/">
   <!-- at root level, make your table -->
   <table>
     <thead>.... </thead>
     <tbody>
       <!-- push the rows through, make sure the path is correct -->
       <xsl:apply-templates select="path/to/row" />
     </tbody>
   </table>
</xsl:template>

<xsl:template match="row">
   <!-- create the rows -->
   <tr>
     <!-- process first entry only, as you requested (why?) -->
     <xsl:apply-templates select="entry[1]" mode="first"/>
     <!-- process other entries -->
     <xsl:apply-templates select="entry[position() > 1]" mode="other"/>
   </tr>
</xsl:template>

<xsl:template match="entry" mode="first">
   <!-- maybe you want the first cell to be treated specially, i.e. as row header -->
   <th><xsl:value-of select="."/></th>
</xsl:template>

<xsl:template match="entry" mode="other">
   <!-- the other cells -->
   <td><xsl:value-of select="."/></td>
</xsl:template>

Примечание: приведенный выше код не проверен, используйте его в качестве шаблона для собственного кода и данных.

Вывод будет выглядеть примерно так:

<table>
  <thead>....</thead>
  <tbody>
    <tr>
      <th>1.</th>
      <td>foo</td>
      <td>morefoo</td>
    </tr>
    <tr>
      <th>2.</th>
      <td>2foo</td>
      <td>2morefoo</td>
    </tr>
    <tr>....
  </tbody>
</table>
1 голос
/ 20 июля 2010

XSLT ниже создаст эту таблицу:

Serial No  Name   Description
1.         foo    morefoo 
2.         2foo   2morefoo 

Образец документа:

<?xml version="1.0" encoding="utf-8"?>
<document>
  <row>
    <entry>1.</entry>
    <entry>foo</entry>
    <entry>morefoo</entry>
  </row>
  <row>
    <entry>2.</entry>
    <entry>2foo</entry>
    <entry>2morefoo</entry>
  </row>
</document>

XSLT:

<?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:template match="/">
    <html>
      <head>
        <title>Sample</title>
      </head>
      <body>
        <table border="1">
          <tr>
            <th>Serial No</th>
            <th>Name</th>
            <th>Description</th>
          </tr>
          <xsl:apply-templates />
        </table>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="row">
    <tr>
      <xsl:for-each select="entry">
        <td>
          <xsl:value-of select="."/>
        </td>
      </xsl:for-each>
    </tr>
  </xsl:template>

</xsl:stylesheet>
1 голос
/ 20 июля 2010
//row/entry[1]

Это выберет все теги entry, которые являются первыми дочерними элементами родительского узла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...