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')">
在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
这个(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,创建一个名为模板为每个国家测试可能会返回一些其他有用的价值,如税率。
我喜欢选项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 - 麦奎因的建议。
XSLT 2.0还是你坚持1.0? – 2014-09-12 18:52:18
@ C.M Sperberg-McQueen感谢您的帮助! – Anonymous 2014-09-12 19:04:18