WedX - журнал о программировании и компьютерных науках

Таблица стилей XSL - для каждого отображения данных несколько раз. Как я могу это исправить?

После некоторой помощи с помощью этого веб-сайта и учебных пособий я научился синтаксическому анализу и XML-документу с использованием XSLT. У меня есть одна проблема. Я пытаюсь отобразить эти данные XML в таблице с отдельными столбцами для каждого атрибута игрока.

<bbgame> <- Root
    <team vh="V" id="MSU" name="MISSOURI STATE" record="8-2">
        <linescore line="24,36" score="60">
          <lineprd prd="1" score="24"></lineprd>
          <lineprd prd="2" score="36"></lineprd>
        </linescore>
    <player uni="01" code="01" name="Keith Pickens" checkname="PICKENS,KEITH" gp="1">
          <stats fgm="1" fga="3" fgm3="0" fga3="0" ftm="2" fta="3" tp="4" blk="1" stl="1" ast="0" min="15" oreb="0" dreb="2" treb="2" pf="2" tf="0" to="2" dq="0"></stats>
          <statsbyprd prd="1" fgm="0" fga="1" fgm3="0" fga3="0" ftm="0" fta="0" tp="0" blk="0" stl="0" ast="0" min="7" oreb="0" dreb="0" treb="0" pf="2" tf="0" to="1" dq="0"></statsbyprd>
          <statsbyprd prd="2" fgm="1" fga="2" fgm3="0" fga3="0" ftm="2" fta="3" tp="4" blk="1" stl="1" ast="0" min="8" oreb="0" dreb="2" treb="2" pf="0" tf="0" to="1" dq="0"></statsbyprd>
        </player>
    </team>
</bbgame>

У меня две команды. Дома и В гостях определяются командой - vh = "V" или "H". Я только что включил одну команду для краткости. Я записал это соответствие шаблону в свою таблицу стилей. xsl:template match="команда//игрок">

<xsl:template match="team//player">
    <xsl:for-each select="//player">
            <table border="1">
                <tr>
                    <td width="200px"><xsl:value-of select="@checkname"/></td>
                    <td width="50px"> <xsl:value-of select="@fgm"/> </td>
                    <td> <xsl:value-of select="@fga"/></td>
                </tr>
            </table>
        </xsl:for-each>
    </xsl:template>

Однако имена отображаются несколько раз, иногда кажется, что 30, а «fga» и «fgm» вообще не отображаются. Также, когда я пытаюсь вызвать шаблон с помощью отдельной команды, такой как <xsl:apply-templates select="team[@vh='v']//player"/>, он тоже не работает.

Я использую: <xsl:apply-templates select="team//player"/> в теле моего XSL для получения этого шаблона. Все остальные работают правильно, но я уверен, что это синтаксическая или логическая ошибка, которую я не могу понять. Спасибо за помощь. Этот веб-сайт был замечательным ресурсом.

РЕДАКТИРОВАТЬ: добавлен корень, чтобы прояснить любую путаницу.

20.01.2014

  • Я не уверен, но должен ли я включать HTML? Это довольно долго из-за нескольких выходных данных XML. Я просто не был уверен, что это будет полезно. 21.01.2014
  • Было бы полезно, если бы вы показали только HTML, который вы ожидаете от предоставленного вами образца XML. Спасибо! 21.01.2014

Ответы:


1

Если я правильно понимаю вашу проблему, причина, по которой вы получаете вывод отдельных игроков несколько раз, заключается в том, что ваш первый <xsl:template match="team//player"> соответствует всем элементам <player> в любом месте под <team>. Для каждого из них <xsl:for-each select="//player"> соответствует всем элементам <player> в любом месте XML. Таким образом, вы говорите: «Найдите каждого игрока, затем для каждого из них найдите каждого игрока».

Причина, по которой атрибуты не совпадают, заключается в том, что @fgm и @fga являются атрибутами <stats>, а не <player>.

Я подозреваю, что причина, по которой <xsl:apply-templates select="team[@vh='v']//player"/> не работает, заключается в том, что значение вашего атрибута @vh в вашем XML представляет собой букву «V» в верхнем регистре. XPath чувствителен к регистру.

В своем решении я изменил ваш пример входного XML, чтобы включить двух игроков, поскольку это воспроизвело то, что, как я думаю, было вашей проблемой (отдельные игроки выводятся более одного раза).

<team vh="V" id="MSU" name="MISSOURI STATE" record="8-2">
  <linescore line="24,36" score="60">
    <lineprd prd="1" score="24"></lineprd>
    <lineprd prd="2" score="36"></lineprd>
  </linescore>
  <player uni="01" code="01" name="Keith Pickens" checkname="PICKENS,KEITH" gp="1">
    <stats fgm="1" fga="3" fgm3="0" fga3="0" ftm="2" fta="3" tp="4" blk="1" stl="1" ast="0" min="15" oreb="0" dreb="2" treb="2" pf="2" tf="0" to="2" dq="0"></stats>
    <statsbyprd prd="1" fgm="0" fga="1" fgm3="0" fga3="0" ftm="0" fta="0" tp="0" blk="0" stl="0" ast="0" min="7" oreb="0" dreb="0" treb="0" pf="2" tf="0" to="1" dq="0"></statsbyprd>
    <statsbyprd prd="2" fgm="1" fga="2" fgm3="0" fga3="0" ftm="2" fta="3" tp="4" blk="1" stl="1" ast="0" min="8" oreb="0" dreb="2" treb="2" pf="0" tf="0" to="1" dq="0"></statsbyprd>
  </player>
  <player uni="01" code="01" name="Robbie Fowler" checkname="FOWLER,ROBBIE" gp="1">
    <stats fgm="1" fga="3" fgm3="0" fga3="0" ftm="2" fta="3" tp="4" blk="1" stl="1" ast="0" min="15" oreb="0" dreb="2" treb="2" pf="2" tf="0" to="2" dq="0"></stats>
    <statsbyprd prd="1" fgm="0" fga="1" fgm3="0" fga3="0" ftm="0" fta="0" tp="0" blk="0" stl="0" ast="0" min="7" oreb="0" dreb="0" treb="0" pf="2" tf="0" to="1" dq="0"></statsbyprd>
    <statsbyprd prd="2" fgm="1" fga="2" fgm3="0" fga3="0" ftm="2" fta="3" tp="4" blk="1" stl="1" ast="0" min="8" oreb="0" dreb="2" treb="2" pf="0" tf="0" to="1" dq="0"></statsbyprd>
  </player>
</team>

В этом случае следующий XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="https://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="team/player">
    <table border="1">
      <tr>
    <td width="200px"><xsl:value-of select="@checkname"/></td>
    <td width="50px"> <xsl:value-of select="stats/@fgm"/> </td>
    <td> <xsl:value-of select="stats/@fga"/></td>
      </tr>
    </table>
  </xsl:template>
</xsl:stylesheet>

производит этот выходной HTML:

<table border="1">
   <tr>
      <td width="200px">PICKENS,KEITH</td>
      <td width="50px">1</td>
      <td>3</td>
   </tr>
</table>
<table border="1">
   <tr>
      <td width="200px">FOWLER,ROBBIE</td>
      <td width="50px">1</td>
      <td>3</td>
   </tr>
</table>
20.01.2014
  • Спасибо и вам, и Мэтью. Вы оба мне очень помогли. Теперь я вижу правильный код. У меня был последний вопрос, если у вас или Мэтью есть время. По какой-то странной причине после имен я вижу текст Команда в конце каждого списка игроков. Это из-за ‹/команда› в конце каждой группы игроков? Я не уверен, как удалить это? 21.01.2014
  • Трудно сказать, не видя полную таблицу стилей XSLT и входной XML, к которому вы ее применяете. Я бы посоветовал вам предоставить их в новом вопросе. Если возможно, постарайтесь свести их к минимуму, демонстрирующему проблему (при этом сохраняя актуальность). 21.01.2014

  • 2

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

    Под этим я подразумеваю, что вы не ссылаетесь на элементы, которыми вы себя считаете, и тот факт, что вы получаете любую соответствующую информацию, является совпадением. Позволь мне объяснить...

    Соответствие вашему шаблону ищет team//player. Это говорит о том, что ищите player где угодно под командой. Если у вас есть только один игрок, это нормально, но если ваш XML должен выглядеть так, как показано ниже, возможно, вы обращаетесь к неправильному player.

    <team>
      <player>
        <player/>
      </player>
    </team>
    

    В зависимости от того, как выглядит ваш вызов apply-templates, я бы изменил ваше совпадение либо на team/player, либо просто на player.

    Следующая проблема — ваш for-each. В настоящее время ваш шаблон установлен в контексте team/player, как мы только что рассмотрели. Однако ваш for-each установлен на //player, что опять же из-за двойной косой черты ищет player в любом контексте. Вы можете удалить двойную косую черту, но тогда вы будете искать ее в контексте team/player/player, которого не существует. Я думаю, что на данный момент вам, вероятно, не нужен for-each, потому что, если шаблон определен правильно, он должен проходить через все элементы player.

    Последняя часть — это атрибуты в файле value-of. Снова возвращаясь к контексту вашего шаблона, вы будете искать атрибуты в этом месте team/player/@fmg и team/player/@fga, ни один из которых не существует. Вы можете просто обновить выбор, чтобы включить имя элемента stats/@fmg или statsbyprd/@fmg в зависимости от того, из какого элемента вы хотите получить атрибуты.

    20.01.2014
  • Спасибо за помощь. Я смотрю на ваши предложения и мой код сейчас. В моем XML-документе есть 20 игроков, 10 заголовков ‹player› под узлом ‹team vh=V› и 10 под узлом ‹team vh=H›. Я использовал цикл for-each, потому что хотел создать две таблицы, по одной для каждой команды, со всей статистикой. Могу ли я выполнить это без использования цикла for-each, как вы упомянули? Я думал, что простое использование значения будет выбирать только первого «игрока» в каждом узле «команда». 21.01.2014
  • Большое спасибо за Вашу помощь! 21.01.2014
  • Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: [email protected]