2012-05-09 2 views
1

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

Этот ответ имеет следующий код:

<xsl:stylesheet version="1.0" 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
      xmlns:msxsl="urn:schemas-microsoft-com:xslt"> 
<xsl:template match="/"> 
    <xsl:variable name="map"> 
     <map> 
      <entry key="key-1">value1</entry> 
      <entry key="key-2">value2</entry> 
      <entry key="key-3">value3</entry> 
     </map> 
    </xsl:variable> 
    <output> 
     <xsl:value-of select="msxsl:node-set($map)/map/entry[@key='key-1']"/> 
    </output> 
</xsl:template> 

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

Это лучший способ сделать выбор для каждого на карте и сравнить с ним?

Вот отрывок из XML:

значение узла
<document> 
    <content name="PART_DESC_SHORT" type="text" vse-streams="2" u="22" action="cluster" weight="1"> 
    SCREW - ADJUST 
    </content> 
</document> 

Содержание может иметь строку, содержащую аббревиатуру, которую я хочу заменить на полную стоимость.

Спасибо, Пол

+0

Мне нужно найти все ключи и найти, содержится ли ключ в пределах этого значения узлов. Поэтому, если у узла есть: «Brkt Pivot R» измените его на «Bracket Pivot R» –

+0

Если у вас лучший пример (XML-документ и соответствующий желаемый результат), я мог бы помочь. –

+0

@DimitreNovatchev Некоторые аббревиатуры составляют всего 2 буквы типа «Br». Я фактически использую EXSLT, а не Microsoft. Я заметил, что у них есть функция toikenize.Строка PART_DESC_SHORT должна быть обозначена пробелом и применять расширение аббревиатуры для точного соответствия, а не содержать. Я попробовал оба решения ниже. –

ответ

1

Нет необходимости использовать for-each - это XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"> 

    <xsl:output indent="yes" method="xml" /> 

    <xsl:variable name="abbreviations"> 
    <abbreviation key="Brkt Pivot R">Bracket Pivot R</abbreviation> 
    <abbreviation key="Foo">Expanded Foo</abbreviation> 
    <abbreviation key="Bar">Expanded Bar</abbreviation> 
    </xsl:variable> 

    <xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="text()"> 
    <xsl:variable name="text" select="."/> 
    <xsl:variable name="abbreviation" select="msxsl:node-set($abbreviations)/*[@key=$text]"/> 
    <xsl:choose> 
     <xsl:when test="$abbreviation"> 
     <xsl:value-of select="$abbreviation"/> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:copy/> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

</xsl:stylesheet> 

преобразует любой XML в точной копии расширяющейся весь текст, соответствующий аббревиатуру, определенный в переменной abbreviations в вершина.

Если вы хотите расширить аббревиатуры только в определенных элементах, вы можете изменить второй шаблон match="..." rule.

С другой стороны, если вы хотите расширить ЛЮБОЕ вхождение всех сокращений в тексте вам нужна петля - это означает, что рекурсии в XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"> 

    <xsl:output indent="yes" method="xml" /> 

    <xsl:variable name="abbreviations"> 
    <abbreviation key="Brkt">Bracket</abbreviation> 
    <abbreviation key="As">Assembly</abbreviation> 
    <abbreviation key="Foo">Expanded Foo</abbreviation> 
    <abbreviation key="Bar">Expanded Bar</abbreviation> 
    </xsl:variable> 

    <!-- Replaces all occurrences of a string with another within a text --> 
    <xsl:template name="replace"> 
    <xsl:param name="text"/> 
    <xsl:param name="from"/> 
    <xsl:param name="to"/> 
    <xsl:choose> 
     <xsl:when test="contains($text,$from)"> 
     <xsl:value-of select="concat(substring-before($text,$from),$to)"/> 
     <xsl:call-template name="replace"> 
      <xsl:with-param name="text" select="substring-after($text,$from)"/> 
      <xsl:with-param name="from" select="$from"/> 
      <xsl:with-param name="to" select="$to"/> 
     </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:value-of select="$text"/> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

    <!-- Replace all occurences of a list of abbreviation with their expanded version --> 
    <xsl:template name="replaceAbbreviations"> 
    <xsl:param name="text"/> 
    <xsl:param name="abbreviations"/> 
    <xsl:choose> 
     <xsl:when test="count($abbreviations)>0"> 
     <xsl:call-template name="replaceAbbreviations"> 
      <xsl:with-param name="text"> 
      <xsl:call-template name="replace"> 
       <xsl:with-param name="text" select="$text"/> 
       <xsl:with-param name="from" select="$abbreviations[1]/@key"/> 
       <xsl:with-param name="to" select="$abbreviations[1]"/> 
      </xsl:call-template> 
      </xsl:with-param> 
      <xsl:with-param name="abbreviations" select="$abbreviations[position()>1]"/> 
     </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:value-of select="$text"/> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

    <xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="text()"> 
    <xsl:call-template name="replaceAbbreviations"> 
     <xsl:with-param name="text" select="."/> 
     <xsl:with-param name="abbreviations" select="msxsl:node-set($abbreviations)/*"/> 
    </xsl:call-template> 
    </xsl:template> 

</xsl:stylesheet> 

Применяя этот второй XSLT к

<document> 
    <content name="PART_DESC_SHORT" type="text" vse-streams="2" u="22" action="cluster" weight="1"> 
    Brkt Pivot R 
    </content> 
</document> 

производит

<document> 
    <content name="PART_DESC_SHORT" type="text" vse-streams="2" u="22" action="cluster" weight="1"> 
    Bracket Pivot R 
    </content> 
</document> 

Обратите внимание, что:

  • Данное решение предполагает отсутствие аббревиатуры ovelap (например, два отдельных сокращение Brk и Brkt)

  • он использует XSLT 1.0 - лучшее решение, вероятно можно с помощью XSLT 2.0

  • этого вида тяжелой обработки строк, скорее всего, весьма неэффективен в XSLT, это, вероятно, лучше писать функцию расширения на каком-то другом языке и вызывать ее из XSLT.

+0

Единственное, что PART_DESC_SHORT может иметь текст «Brkt Pivot R» или просто «Brkt» или «Brkt As» и т. Д., На самом деле последнее значение будет расширено до «сборки кронштейнов», поскольку 2 члена будут расширены. мой сокращенный ключ просто имел бы «Brkt» в «Bracket» –

+0

Я вижу - я этого не понимал ... Я расширяю/исправляю свой ответ ... – MiMo

+0

Я изменил ваш оператор выбора на: