2010-12-15 3 views
1

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

Я пришел с этим:

<?xml version="1.0" encoding="utf-8"?>  
<xsl:stylesheet  
     version="1.0"  
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
     xmlns:tmp="http://tempuri.org"  
     exclude-result-prefixes="tmp"  
>  
     <xsl:output method="xml" indent="yes"/> 

     <tmp:sorting-criterion>  
      <code value="A">5</code>  
      <code value="B">1</code>  
      <code value="C">3</code>  
     </tmp:sorting-criterion> 

     <xsl:template match="/InputValueParentNode">  
      <xsl:element name="OutputValues">  
      <xsl:for-each select="InputValue">  
        <xsl:sort select="document('')/*/tmp:sorting-criterion/code[@value=substring(.,1,1)]" data-type="number"/>  
        <xsl:value-of select="normalize-space(.)"/> 
        <xsl:if test="position() != last()">  
          <xsl:text>,</xsl:text>  
        </xsl:if> 
      </xsl:for-each>  
      </xsl:element>  
     </xsl:template>  
</xsl:stylesheet> 

Он не работает и выглядит как XPath document('')/*/tmp:sorting-criterion/code[@value=substring(.,1,1)] не оценивает, как я ожидал. Я проверил, чтобы заменить substring(.,1,1) на литерал, и он оценивает правильное значение.

Итак, я пропустил что-то, что делает выражение XPath сортировки не оцениваемым, как я ожидаю, или это просто невозможно сделать так?

Если не удается создать выражение XPath, которое работает, есть ли работа для достижения моей цели?

Примечание: Я вынужден XSLT-1.0

Пример ввода:

<?xml version="1.0" encoding="utf-8"?> 
<InputValueParentNode> 
     <InputValue>A input value</InputValue> 
     <InputValue>B input value</InputValue> 
     <InputValue>C input value</InputValue> 
</InputValueParentNode> 

Ожидаемое Ouput:

<?xml version="1.0" encoding="utf-8"?> 
<OutputValues>B input value,C input value,A input value</OutputValues> 
+0

могли бы вы предоставить пример ввода и ожидаемых результатов? – wdebeaum 2010-12-15 15:35:54

+0

@wdebeaum: вопрос отредактирован, чтобы включить оба. Приветствия. – 2010-12-15 15:52:06

ответ

2

Заменить self::node() аббревиатуру ., с current() функция.

Лучше предикат будет: starts-with(normalize-space(current()),@value)

0

Помимо изменения трансформации в соответствии с Alejandro´s answer, я обнаружил, что лучше использовать переменный для XSL-й картографических данных, чтобы избежать деклараций фиктивного пространства имен (TMP), как показано на Dimitre´s answer to another related question.

Моя последняя реализация:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet 
     version="1.0" 
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
> 
     <xsl:output method="xml" indent="yes"/> 

     <xsl:template match="/InputValueParentNode"> 
      <xsl:variable name="sorting-map"> 
        <i code="A" priority="5"/> 
        <i code="B" priority="1"/> 
        <i code="C" priority="3"/> 
      </xsl:variable> 
      <xsl:variable name="sorting-criterion" select="document('')//xsl:variable[@name='sorting-map']/*"/> 

      <xsl:element name="OutputValues"> 
      <xsl:for-each select="InputValue"> 
        <xsl:sort select="$sorting-criterion[@code=substring(normalize-space(current()),1,1)]/@priority" data-type="number"/> 
        <xsl:value-of select="normalize-space(current())"/> 
        <xsl:if test="position() != last()"> 
          <xsl:text>,</xsl:text> 
        </xsl:if> 
      </xsl:for-each> 
      </xsl:element> 
     </xsl:template> 
</xsl:stylesheet> 
Смежные вопросы