XSL有条件的噩梦

问题描述:

我在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? – 2014-09-12 18:52:18

+0

@ C.M Sperberg-McQueen感谢您的帮助! – Anonymous 2014-09-12 19:04:18

在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)最好使用**键**从名单。 – 2014-09-12 19:41:49

你可以做类似下面的事情。它可能只是略微整理你的东西。

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

选项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 2014-09-12 19:03:16

如果你正在寻找只是为了简化现有的方法,那么你可以使用类似:

<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 Sperberg - 麦奎因的建议。