XSLT содержит два периода - PullRequest
       17

XSLT содержит два периода

2 голосов
/ 16 декабря 2010

У меня есть HTML-документ, который использовал неупорядоченный список для отображения навигации. Когда он выводится как XML, он больше не использует список, а вместо этого присваивает каждой ссылке <Description>. Способ работы описания заключается в том, что основным ссылкам присваиваются номера, такие как 100, 200, 300, 400 и т. Д. Субнавигационные ссылки из них назначаются следующим образом: 200.100, 200.200, 200.300 и т. Д.

XML выглядит следующим образом:

<Items>
  <PgIndexElementItem>
      <Description>100</Description>
      <Title>This is the Title</Title>
  </PgIndexElementItem>
  <PgIndexElementItem>
      <Description>200</Description>
      <Title>This is the Title</Title>
  </PgIndexElementItem>
  <PgIndexElementItem>
      <Description>200.100</Description>
      <Title>This is the Title</Title>
  </PgIndexElementItem>
  <PgIndexElementItem>
      <Description>200.100.100</Description>
      <Title>This is the Title</Title>
  </PgIndexElementItem>
</Items>

Если вы посмотрите на последний PgIndexElementItem, есть три набора чисел.

Я пытаюсь воссоздать неупорядоченный список, используя XSLT. Это то, что я делал до сих пор:

<ul>
    <xsl:for-each select="//PgIndexElementItem">
        <xsl:if test="not(contains(Description, '.'))">
            <li><a href="{ResolvedURL/ServerRelative}"><xsl:value-of select="Title"/></a>
                <ul>
                    <xsl:for-each select="//PgIndexElementItem">
                        <xsl:if test="contains(Description, '.')">
                            <li><a href="{ResolvedURL/ServerRelative}"><xsl:value-of select="Title"/></a></li>
                        </xsl:if>
                    </xsl:for-each>
                </ul>
            </li>
        </xsl:if>
    </xsl:for-each>
</ul>

Мой вопрос был бы, есть ли способ указать contains(Description, который нацелен на описания с двумя периодами, как последний PgIndexElementItem выше?

Надеюсь, я объяснил это достаточно хорошо. Я не знаю, как сделать это менее запутанным. Заранее спасибо!

EDIT

o Graduate Program
   * How to Apply
   * Masters Program
        o M.A. Handbook
        o FAQs
        o Alumni
        o Masters Theses
        o Sample Thesis Proposals
   * M.A. Handbook
   * FAQs
   * Alumni
   * Masters Theses
   * Sample Thesis Proposals

Ответы [ 3 ]

2 голосов
/ 16 декабря 2010

Используйте

string-length(Description) - string-length(translate(Description, '.',''))  = 2

Это работает одинаково для любого числа $n (в то время как метод "подстрока-после" просто невозможно использовать в общем случае):

string-length(Description) - string-length(translate(Description, '.',''))  = $n
2 голосов
/ 16 декабря 2010

Вы можете использовать

<xsl:if test="contains(substring-after(Description, '.'), '.')">
    ...

, чтобы проверить, есть ли у элемента дочерний элемент Описание с двумя или более периодами.

Однако вместо этого я бы изменил ваш XSLT на:

  <!-- this part replaces your <ul> code above -->
  <ul>
     <xsl:apply-templates
         select="//PgIndexElementItem[not(contains(Description, '.'))]" />
  </ul>      

Обновлен этот шаблон:

<!-- add this new template -->
<xsl:template match="PgIndexElementItem">
   <li>
      <a href="{ResolvedURL/ServerRelative}"><xsl:value-of select="Title"/></a>
      <xsl:variable name="prefix" select="concat(Description, '.')"/>
      <xsl:variable name="childOptions"
         select="../PgIndexElementItem[starts-with(Description, $prefix)
           and not(contains(substring-after(Description, $prefix), '.'))]"/>
      <xsl:if test="$childOptions">
         <ul>
            <xsl:apply-templates select="$childOptions" />
         </ul>
      </xsl:if>
   </li>
</xsl:template>

Это позволит избежать ненужного дублирования кода и нежелательных пустых элементов <ul>.

Я сделал несколькопредположения о том, как должны описываться дочерние элементы описания ... например, "200.100" должно отображаться в подсписке под "200", но не под "100".

0 голосов
/ 16 декабря 2010

Похоже, вы имеете дело с вложенными элементами PgIndexElementItem - если они вложены в несколько слоев, вам следует рассмотреть возможность рефакторинга вашего XSL для использования рекурсивного шаблона (предполагая, что вывод HTML для каждого уровня предсказуем).

Как написано, ваш цикл for-each выбирает всех потомков PgIndexElementItem текущего элемента, а затем делает это снова , когда он попадает во внутренний цикл for-each. Возможно, не то, что вы хотели.

...