2010-12-16 4 views
2

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

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

поддерживает ваш синтаксический анализатор xpath 2 или xslt 2? – 2010-12-16 19:40:16

+0

Не уверен. Как мне это узнать? Извините, весь новый мир с этим. – jrottier 2010-12-16 19:44:41

+0

@jrottier, с какой технологией вы запускаете этот код? – 2010-12-16 19:50:31

ответ

2

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

<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».

2

Использование:

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

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

string-length(Description) - string-length(translate(Description, '.','')) = $n 
0

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

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

Смежные вопросы