Как бороться с тегами типа "«? - PullRequest
0 голосов
/ 15 сентября 2010

Я очень плохо знаком с XSL и у меня возникли некоторые проблемы.

Используемый мной XML имеет несколько тегов, таких как <Example/>.

в моем XSL (вывод HTML) я использовал что-то подобное для тегов без данных:

<xsl:if test="count(ContractNr) > 0">  
  <td>Nr:</td>  
  <td><xsl:value-of select="ContractNr"/></td>  
</xsl:if>

Отлично работает, когда нет тега.

но как мне сделать <xsl:if> для чего-то вроде <ContractNumber/>?
Тай, и прости за мой английский.

ОБНОВЛЕНИЕ : редактировал мой 1 пост, извините ... я имел в виду, что мой пример работает, когда тестируемый тег отсутствует в xml, но как мне проверить, является ли тег "пустым" как или

Ты, Treemonkey, но я не уверен, что это решение, которое я ищу.

Я постараюсь объяснить лучше.

во входном файле xml есть много тегов, которые являются "необязательными" или "minOccurs =" 0 "" (согласно схеме). используя xsl, я пытаюсь сделать вывод html с таблицей, в которой я использую <xsl:if>, чтобы определить, присутствует ли тег в xml или нет (нет тега = нет столбца).

Я даю статические имена столбцам моей таблицы html (данные в xml нельзя использовать для именования) и помещаю туда данные из xml. Теперь, когда тег равен <smthng/>, я все еще получаю столбец с заданным статическим именем - и это проблема. Я хотел бы сделать xsl:if, чтобы при наличии <smthng/> столбец не создавался:

<table>
  <tr><xsl:if ...>
    <td>Some name:</td>
    <td><xsl:value-of select="smthng"/></td></xsl:if>
  </tr>
</table>

Ответы [ 5 ]

1 голос
/ 15 сентября 2010
<xsl:if test="count(ContractNr) &gt; 0">
  <td>Nr:</td>
  <td><xsl:value-of select="ContractNr"/></td>
</xsl:if>

Это плохо XSLT .

Лучшее использование :

<xsl:apply-templates select="ContractNr[1]"/>

и имеют отдельный шаблон :

<xsl:template match="ContractNr/text()">
 <td>Nr:</td>
 <td><xsl:value-of select="."/></td>
</xsl:template>

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

0 голосов
/ 15 сентября 2010

Два решения для того, что я думаю, это то, что вы хотите.

С этим входом:

<table>
   <row>
      <a>A1</a>
      <b>B1</b>
      <c>C1</c>
   </row>
   <row>
      <a>A2</a>
      <b>B2</b>
   </row>
   <row>
      <a>A3</a>
      <b/>
      <c>C3</c>
   </row>
</table>

Эта таблица стилей:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:h="header"
 exclude-result-prefixes="h">
    <h:header title="First" element="a"/>
    <h:header title="Second" element="b"/>
    <h:header title="Third" element="c"/>
    <xsl:template match="table">
        <html>
            <table style="border:1px solid black;">
                <tr>
                    <xsl:apply-templates select="document('')/*/h:*"
                     mode="header"/>
                </tr>
                <xsl:apply-templates/>
            </table>
        </html>
    </xsl:template>
    <xsl:template match="row">
        <tr>
            <xsl:apply-templates select="document('')/*/h:*">
                <xsl:with-param name="pContext" select="."/>
            </xsl:apply-templates>
        </tr>
    </xsl:template>
    <xsl:template match="h:*">
        <xsl:param name="pContext"/>
        <td>
            <xsl:value-of select="$pContext/*[name()=current()/@element]"/>
        </td>
    </xsl:template>
    <xsl:template match="h:*" mode="header">
        <th>
            <xsl:value-of select="@title"/>
        </th>
    </xsl:template>
</xsl:stylesheet>

Выход:

<html>
    <table style="border:1px solid black;">
        <tr>
            <th>First</th>
            <th>Second</th>
            <th>Third</th>
        </tr>
        <tr>
            <td>A1</td>
            <td>B1</td>
            <td>C1</td>
        </tr>
        <tr>
            <td>A2</td>
            <td>B2</td>
            <td></td>
        </tr>
        <tr>
            <td>A3</td>
            <td></td>
            <td>C3</td>
        </tr>
    </table>
</html>

И эта другая таблица стилей:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:h="header"
 exclude-result-prefixes="h">
    <h:header title="First" element="a"/>
    <h:header title="Second" element="b"/>
    <h:header title="Third" element="c"/>
    <xsl:template match="table">
        <html>
            <xsl:apply-templates/>
        </html>
    </xsl:template>
    <xsl:template match="row">
        <table style="border:1px solid black;">
            <xsl:apply-templates select="document('')/*/h:*">
                <xsl:with-param name="pContext" select="."/>
            </xsl:apply-templates>
        </table>
    </xsl:template>
    <xsl:template match="h:*">
        <xsl:param name="pContext"/>
        <tr>
            <th>
                <xsl:value-of select="@title"/>
            </th>
            <td>
                <xsl:value-of select="$pContext/*[name()=current()/@element]"/>
            </td>
        </tr>
    </xsl:template>
</xsl:stylesheet>

Выход:

<html>
    <table style="border:1px solid black;">
        <tr>
            <th>First</th>
            <td>A1</td>
        </tr>
        <tr>
            <th>Second</th>
            <td>B1</td>
        </tr>
        <tr>
            <th>Third</th>
            <td>C1</td>
        </tr>
    </table>
    <table style="border:1px solid black;">
        <tr>
            <th>First</th>
            <td>A2</td>
        </tr>
        <tr>
            <th>Second</th>
            <td>B2</td>
        </tr>
        <tr>
            <th>Third</th>
            <td></td>
        </tr>
    </table>
    <table style="border:1px solid black;">
        <tr>
            <th>First</th>
            <td>A3</td>
        </tr>
        <tr>
            <th>Second</th>
            <td></td>
        </tr>
        <tr>
            <th>Third</th>
            <td>C3</td>
        </tr>
    </table>
</html>

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

0 голосов
/ 15 сентября 2010

Я отредактировал свой 1 пост, извините ... я имел в виду, что мой пример <xsl:if> работает, когда тестируемый тег отсутствует в xml, но как мне проверить, является ли тег "пустым", как <smthng/> или <smthng></smthng>

ты, Treemonkey, но я не уверен, что это решение, которое я ищу.

Я постараюсь объяснить лучше.

во входном файле xml есть много тегов, которые являются "необязательными" или "minOccurs =" 0 "" (согласно схеме). используя xsl, я пытаюсь сделать вывод html с таблицей, в которой я использую <xsl:if>, чтобы определить, присутствует ли тег в xml или нет (нет тега = нет столбца).
Я даю статические имена столбцам моей HTML-таблицы (данные в XML не могут быть использованы для именования) и помещаю туда данные из XML. Теперь, когда тег равен <smthng/>, я все еще получаю столбец с заданным статическим именем - и это проблема. Я хотел бы сделать xsl: если так, если есть <smthng/> столбец не сделан:
<table><br> <tr><xsl:if ...><br> <td>Some name:</td><br> <td><xsl:value-of select="smthng"/></td></xsl:if><br> </tr><br> </table>

0 голосов
/ 15 сентября 2010

Это то, что вы ищете? Это проверит наличие элемента, а затем позволит вам использовать имя узла, используя функцию local-name ()

это также ответит на ваш второй вопрос, поскольку применение шаблонов для узла будет применять шаблон только к соответствующим элементам, так что работает почти так же, как и IF, как, естественно, если нет соответствия, ничего не произойдет!

<xsl:template match="/">
<xsl:apply-templates select="ContractNumber"/>
</xsl:template>

<xsl:template match="ContractNumber">
<div>
<xsl:value-of select="local-name()"/>
</div>
</xsl:template>

Вы можете использовать следующее

<xsl:if test="ContractNumber=''"> do stuff </xsl:if>

или

<xsl:choose>
<xsl:when test="ContractNumber=''">
   <!--do nothing-->
</xsl:when>
<xsl:otherwise>
   <!--build table -->
</xsl:otherwise>
</xsl:choose>
0 голосов
/ 15 сентября 2010

Разве <ContractNumber></ContractNumber> не совпадает с <ContractNumber/>?

См. Ссылку на XML: http://www.w3.org/TR/xml/#sec-starttags

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