XSL有条件的噩梦

时间:2014-09-12 18:36:51

标签: xslt

我在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')">

4 个答案:

答案 0 :(得分: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,就此而言)中,您可以将相关信息放在外部文档(称为states.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

答案 1 :(得分: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,创建一个命名模板来测试每个州,或许返回一些其他有用的值,如税率。

答案 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>

答案 3 :(得分: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>

但是,我建议您考虑按照C. M. Sperberg-McQueen的建议,保持XML格式的状态到产品查找表。