2016-08-26 4 views
1

У меня есть большой xsl: выберите (например, ~ 100), где xsl: при тестировании с использованием регулярного выражения. Я ищу более чистый способ, может ли это быть заменено справочной таблицей? Это всего лишь пример моего кода выглядит сегодняПоиск в XSLT с использованием регулярного выражения

<xsl:when test="matches($seq4, '^\w+-\w+-\w+-\d+/NCell:.+$', 'i')"> 
<xsl:value-of select="'NEIGHBOR'"/> 
</xsl:when> 
<xsl:when test="matches($seq4, '(/ULoCell:NodeB Function Name=.*, Local Cell ID=.*)', 'i')"> 
<xsl:value-of select="'SECTOR'"/> 
</xsl:when> 

Я ценю помощь, и я думаю, что я могу сделать код работу Карты образца, если я сделаю это отдельный XML-файл и использовать импорт или включить. Мне просто интересно, как сложно было бы преобразовать это в поиск документа. Я знаком с поиском документов и ключами, но я понятия не имею, как бы закодировать поиск с помощью регулярного выражения? У меня есть следующий документ: подстановок

<Telsa xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <Row Key1="^[A-Z0-9]+/Cell:eNodeB Function Name=[A-Z0-9]+, Local Cell ID=[0-9]+, Cell Name=.*/CnOperator:CnOperatorId=[0-9]+$" ElementType="CELL_CORE_OPERATOR" RegexReplace="&apos;^([A-Z0-9]+)/Cell:eNodeB Function Name=[A-Z0-9]+, Local Cell ID=([0-9]+), Cell Name=.*/CnOperator:(CnOperatorId=[0-9]+)&apos;, &apos;$1/CELL:$2/$3&apos;"></Row> 
    <Row Key1="^\w+-\w+-\w+-\d+/Cell:eNodeB Function Name=[A-Z0-9]+, Local Cell ID=[0-9]+, Cell Name=.*, eNodeB ID=[0-9]+, Cell.*$" ElementType="CELL" RegexReplace="&apos;^\w+-\w+-\w+-\d+/Cell:eNodeB Function Name=([A-Z0-9]+), Local Cell ID=([0-9]+), Cell Name=.*, eNodeB ID=([0-9]+), Cell.*$&apos;, &apos;$1/Cell:$2&apos;"></Row> 
    <Row Key1="^\w+-\w+-\w+-\d+/EthernetInterface:Ethernet Interface No.=.*$" ElementType="EthernetInterface" RegexReplace="&apos;^(\w+-\w+-\w+-\d+)/EthernetInterface:Ethernet Interface No.=([0-9]+)$&apos; , &apos;$1/No=$2&apos;"></Row> 
    <Row Key1="^[A-Z0-9]+/CELL:Local cell identity=[0-9]+, Cell Name=.*/OPERATOR:CnOperatorId=[0-9]+$" ElementType="CELL_CORE_OPERATOR" RegexReplace="&apos;^([A-Z0-9]+/CELL:)Local cell identity=([0-9]+), Cell Name=.*/OPERATOR:(CnOperatorId=[0-9]+)&apos; , &apos;$1$2/$3&apos;"></Row> 
    <Row Key1="^[A-Z0-9]+/Cell:Local cell identity=[0-9]+, Cell Name=.*, eNodeB identity=[0-9]+$" ElementType="CELL" RegexReplace="&apos;^([A-Z0-9]+/Cell:)Local cell identity=([0-9]+), Cell Name=.*, eNodeB identity=[0-9]+$&apos;, &apos;$1$2&apos;"></Row> 
    <Row Key1="^[A-Z0-9]+/Cell:eNodeB Function Name=[A-Z0-9]+, Local Cell ID=[0-9]+, Cell Name=.*, eNodeB ID=[0-9]+$" ElementType="CELL" RegexReplace="&apos;^([A-Z0-9]+)/Cell:eNodeB Function Name=[A-Z0-9]+, Local Cell ID=([0-9]+), Cell Name=.*, eNodeB ID=([0-9]+)$&apos;, &apos;$1/Cell:$2&apos;"></Row> 
    <Row Key1="^[A-Z0-9]+/Cell:eNodeB Function Name=[A-Z0-9]+, Local Cell ID=[0-9]+, Cell Name=.*, eNodeB ID=[0-9]+$" ElementType="CELL" RegexReplace="&apos;^([A-Z0-9]+)/Cell:eNodeB Function Name=[A-Z0-9]+, Local Cell ID=([0-9]+), Cell Name=.*, eNodeB ID=([0-9]+)$&apos;, &apos;$1/Cell:$2&apos;"></Row> 
</Telsa> 

Я бы определить поиск с

<xsl:key name="table-lookup" match="Row" use="@Key1"/> 
<xsl:variable name="LookupDoc" select="document('Telsa.xml')/Telsa"/> 

Как закодировать ключ поиска, хотя?

<xsl:value-of select="key('table-lookup', $curr_key, $LookupDoc)/@ElementType"/> 

ответ

1

Возможно следующее, что вы ищете, он сохраняет регулярные выражения, флаги, и в результате в структуре XML, а затем смотрит на первую найденную элемент:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xs" 
    version="2.0"> 

    <xsl:param name="pattern-map" as="element(map)*"> 
     <map pattern="^\w+-\w+-\w+-\d+/NCell:.+$" flags="i">NEIGHBOR</map> 
     <map pattern="(/ULoCell:NodeB Function Name=.*, Local Cell ID=.*)" flags="i">SECTOR</map> 
    </xsl:param> 

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

    <xsl:template match="item"> 
     <xsl:copy> 
      <xsl:value-of select="$pattern-map[matches(current(), @pattern, @flags)][1]"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

При запуске против

<root> 
    <item>a-b-c-1/NCell:x</item> 
    <item>/ULoCell:NodeB Function Name=x, Local Cell ID=.y</item> 
</root> 

выход

<root> 
    <item>NEIGHBOR</item> 
    <item>SECTOR</item> 
</root> 

Будьте осторожны, если ваши регулярные выражения содержат фигурные скобки { или } как с литеральным элементом результата, например <map pattern="\w{2}" flags="i">foo</map>, это будет интерпретироваться как шаблон значения атрибута, поэтому вам нужно будет удвоить их, как в <map pattern="\w{{2}}" flags="i">foo</map>.

+0

Единственным недостатком этого является то, что реализация match() может быть более эффективной, если регулярное выражение известно статически, то есть, если оно записано как строковый литерал внутри вызова функции, –

0

Мне нравится это решение, единственный вопрос заключается в том, может ли эта логика быть помещена во внешний документ, похожий на таблицу поиска?

+0

Вы опубликовали, что выглядит как комментарий в качестве ответа. Если вы ссылаетесь на мой ответ, я сделал «шаблон-карту» глобальным параметром, который можно передать в таблицу стилей перед запуском преобразования. Если вы хотите использовать внешний документ, возможно, было бы легче изменить тип параметра как документа, но в общем случае, пока используется глобальный параметр, вы можете поддерживать отображение вне кода XSLT. –

+0

Насколько сложно было бы превратить это в поиск документа вместо поиска карты. Причина, по которой я спрашиваю, мне легче экспортировать данные. – Hans

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