2014-09-12 2 views
2

У меня очень длинный или условный в XSL, который работает, но он абсолютно уродлив. Когда я получаю заказ, в зависимости от того, какое состояние заказа из другого продукта открывается. Какой был бы лучший способ похудения? Любая помощь будет оценена.XSL условный кошмар

($document_Input_1/OrderInfo/foo/bar/state)=('AZ') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('CO') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('CT') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('DC') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('IL') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('KY') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('LA') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('MA') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('MD') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('ME') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('MI') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('MN') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('MO') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('MS') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('MT') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('NE') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('NV') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('OH') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('RI') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('SC') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('TN') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('VA') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('WI') 
or ($document_Input_1/OrderInfo/foo/bar/state)=('WV')"> 
+2

XSLT 2.0 или вы застряли с 1.0? –

+0

@ C.M Sperberg-McQueen благодарит меня за очищение! – Anonymous

ответ

4

В XSLT 2.0, более простой способ, чтобы написать это:

$document_Input_1/OrderInfo/foo/bar/state 
= 
('AZ', 'CO', 'CT', 'DC', 'IL', 'KY', 
    'LA', 'MA', 'MD', 'ME', 'MI', 'MN', 
    'MO', 'MS', 'MT', 'NE', 'NV', 'OH', 
    'RI', 'SC', 'TN', 'VA', 'WI', 'WV') 

В XSLT 1.0 (и 2.0, по этому вопросу), вы могли бы поместить соответствующую информацию во внешнем документе (назовем это заявляет. XML) со структурой, как это:

<states> 
    <group product="P1"> 
    <state id="AK"/> 
    ... 
    </group> 
    <group product="P2"> 
    <state id='AZ'/> 
    <state id='CO'/> 
    ... 
    <state id='WI'/> 
    <state id='WV'/> 
    </group> 
</states> 

Теперь ваше выражение может быть

$document_Input_1/OrderInfo/foo/bar/state 
= 
document('states.xml') 
//group[@product='P2']/state/@id 

Или если состояния сгруппированы по-разному, это может быть проще организовать states.xml так:

<states> 
    <state id="AK" product="P1"/> 
    <state id="AL" product="P1"/> 
    <state id='CO' product="P2"/> 
    <state id='CT' product="P2"/> 
    ... 
    <state id='WV' product="P2"/> 
</states> 

Теперь вы можете выразить свое состояние как

$document_Input_1/OrderInfo/foo/bar/state 
= 
document('states.xml') 
//state[@product='P2']/@id 
+0

Это (версия XSLT 1.0), безусловно, правильный подход (возможно, даже для приложения XSLT 2.0), поскольку он отделяет данные от логики. Я бы добавил, что (1) список можно было бы просто сохранить в самой таблице стилей либо как переменную, либо под другим пространством имен, и (2) было бы лучше использовать ** ** для поиска из список. –

1

Вы можете сделать что-то похожее на следующее. Это может лишь слегка разгладить то, что у вас есть.

<xsl:for-each select="$document_Input_1/OrderInfo/foo/bar/state"> 
<xsl:if test="text() = 'AZ' or 
      text() = 'CO' or 
      text() = 'CT' or 
      text() = 'DC'">  
    <!-- do whatever --> 
</xsl:if> 
</xsl:for-each> 
2

Вариант 1, упростить XPATH

<xsl:variable name="test" select="$document_Input_1/OrderInfo/foo/bar/state/text()"/> 
<xsl:if test="$test='AZ' or $test='CO' ..."> 

Вариант 2, испытание для каждого состояния в XSL: выберите

<xsl:variable name="test" select="$document_Input_1/OrderInfo/foo/bar/state/text()"/> 
<xsl:variable name="result"> 
    <xsl:choose> 
    <xsl:when test="$test='AZ'>1</xsl:when> 
    <xsl:when test="$test='CO'>1</xsl:when> 
    ... 
    </xsl:choose> 

Вариант 3, создать именованный шаблон чтобы проверить, чтобы каждое государство, возможно, возвращало другое полезное значение, такое как ставка налога.

+0

Мне нравится идея варианта 2. Я собираюсь попробовать это, как только вернусь в офис. – Anonymous

1

Если вы ищете только для оптимизации существующий подход, то вы могли бы использовать что-то вроде:

<xsl:variable name="product1" select="'-AZ-CO-CT-DC-IL-KY-LA-MA-MD-ME-MI-MN-MO-MS-MT-NE-NV-OH-RI-SC-TN-VA-WI-WV-'" /> 
<xsl:variable name="product2" select="'-AK-DE-FL-GA-HI-ID-IL-IA-OR-PA-SD-WY-'" /> 
<xsl:variable name="product3" select="'-AR-CA-CO-IN-KS-LA-MH-NH-OK-'" /> 
<xsl:variable name="state" select="concat('-', $document_Input_1/OrderInfo/foo/bar/state, '-')" /> 

<xsl:choose> 
    <xsl:when test="contains($product1, $state)">product1</xsl:when> 
    <xsl:when test="contains($product2, $state)">product2</xsl:when> 
    <xsl:when test="contains($product3, $state)">product3</xsl:when> 
    ... 
</xsl:choose> 

Однако, я хотел бы призвать вас рассмотреть вопрос о сохранении таблицы поиска состояния к продукту в формате XML, как это было предложено CM Сперберг-McQueen.

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