xpath中的嵌套条件if-else语句
我有以下XML:xpath中的嵌套条件if-else语句,xpath,conditional,if-statement,xpath-2.0,Xpath,Conditional,If Statement,Xpath 2.0,我有以下XML: <property id="1011"> <leasehold>No</leasehold> <freehold>Yes</freehold> <propertyTypes> <propertyType>RESIDENTIAL</propertyType> </propertyTypes> </property>
<property id="1011">
<leasehold>No</leasehold>
<freehold>Yes</freehold>
<propertyTypes>
<propertyType>RESIDENTIAL</propertyType>
</propertyTypes>
</property>
我已经看到了贝克尔的方法,但我不能真正遵循它。XPath并不是我的强项。试试这个
if (condition)
then
if (condition) stmnt
else stmnt
else
if (condition) stmnt
else stmnt
I.在XPath 2.0中,只需将其转换为:
if(/*/propertyTypes/propertyType = 'RESIDENTIAL')
then
(if(/*/leasehold='Yes')
then 'Rent'
else 'Buy'
)
else
if(/*/leasehold='Yes')
then 'Leasehold'
else 'Freehold'
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:sequence select=
"if(/*/propertyTypes/propertyType = 'RESIDENTIAL')
then
(if(/*/leasehold='Yes')
then 'Rent'
else 'Buy'
)
else
if(/*/leasehold='Yes')
then 'Leasehold'
else 'Freehold'
"/>
</xsl:template>
</xsl:stylesheet>
<property id="1011">
<leasehold>No</leasehold>
<freehold>Yes</freehold>
<propertyTypes>
<propertyType>RESIDENTIAL</propertyType>
</propertyTypes>
</property>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select=
"concat(
substring('rent',
1 div boolean(/*[leasehold='Yes'
and
propertyTypes/propertyType = 'RESIDENTIAL'
]
)
),
substring('buy',
1 div not(/*[leasehold='Yes'
and
propertyTypes/propertyType = 'RESIDENTIAL'
]
)
)
)
"/>
</xsl:template>
</xsl:stylesheet>
基于XSLT2.0的验证:
if(/*/propertyTypes/propertyType = 'RESIDENTIAL')
then
(if(/*/leasehold='Yes')
then 'Rent'
else 'Buy'
)
else
if(/*/leasehold='Yes')
then 'Leasehold'
else 'Freehold'
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:sequence select=
"if(/*/propertyTypes/propertyType = 'RESIDENTIAL')
then
(if(/*/leasehold='Yes')
then 'Rent'
else 'Buy'
)
else
if(/*/leasehold='Yes')
then 'Leasehold'
else 'Freehold'
"/>
</xsl:template>
</xsl:stylesheet>
<property id="1011">
<leasehold>No</leasehold>
<freehold>Yes</freehold>
<propertyTypes>
<propertyType>RESIDENTIAL</propertyType>
</propertyTypes>
</property>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select=
"concat(
substring('rent',
1 div boolean(/*[leasehold='Yes'
and
propertyTypes/propertyType = 'RESIDENTIAL'
]
)
),
substring('buy',
1 div not(/*[leasehold='Yes'
and
propertyTypes/propertyType = 'RESIDENTIAL'
]
)
)
)
"/>
</xsl:template>
</xsl:stylesheet>
II。XPath 1.0解决方案 在XPath1.0中没有
if
操作符
条件语句仍然可以用单个XPath 1.0表达式实现,但这更复杂,并且表达式可能不太可读和可理解
以下是一种通用方法(由Jeni Tennison首次提出),用于在条件$cond
为true()
时生成$stringA
,否则生成$stringB
:
concat(substring($stringA, 1 div $cond), substring($stringB, 1 div not($cond)))
此公式的主要成就之一是它适用于任何长度的字符串,无需指定长度
说明:
if(/*/propertyTypes/propertyType = 'RESIDENTIAL')
then
(if(/*/leasehold='Yes')
then 'Rent'
else 'Buy'
)
else
if(/*/leasehold='Yes')
then 'Leasehold'
else 'Freehold'
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:sequence select=
"if(/*/propertyTypes/propertyType = 'RESIDENTIAL')
then
(if(/*/leasehold='Yes')
then 'Rent'
else 'Buy'
)
else
if(/*/leasehold='Yes')
then 'Leasehold'
else 'Freehold'
"/>
</xsl:template>
</xsl:stylesheet>
<property id="1011">
<leasehold>No</leasehold>
<freehold>Yes</freehold>
<propertyTypes>
<propertyType>RESIDENTIAL</propertyType>
</propertyTypes>
</property>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select=
"concat(
substring('rent',
1 div boolean(/*[leasehold='Yes'
and
propertyTypes/propertyType = 'RESIDENTIAL'
]
)
),
substring('buy',
1 div not(/*[leasehold='Yes'
and
propertyTypes/propertyType = 'RESIDENTIAL'
]
)
)
)
"/>
</xsl:template>
</xsl:stylesheet>
这里我们使用的事实是,根据定义:
number(true()) = 1
及
那
1 div 0 = Infinity
因此,如果$cond
为false
,则上面concat()
的第一个参数为:
substring($stringA, Infinity)
sibstring($stringA, 1)
这是空字符串,因为$stringA
的长度是有限的
另一方面,如果$cond
是true()
,则上面concat()
的第一个参数是:
substring($stringA, Infinity)
sibstring($stringA, 1)
这只是$stringA
因此,根据$cond
的值,上面concat()
的两个参数中只有一个是非空字符串(分别是$stringA
或$stringB
)
将此通用公式应用于特定问题,我们可以将大条件表达式的前半部分转换为:
concat(
substring('rent',
1 div boolean(/*[leasehold='Yes'
and
propertyTypes/propertyType = 'RESIDENTIAL'
]
)
),
substring('buy',
1 div not(/*[leasehold='Yes'
and
propertyTypes/propertyType = 'RESIDENTIAL'
]
)
)
)
这将使您了解如何将整个条件表达式转换为单个XPath 1.0表达式
基于XSLT 1.0的验证:
if(/*/propertyTypes/propertyType = 'RESIDENTIAL')
then
(if(/*/leasehold='Yes')
then 'Rent'
else 'Buy'
)
else
if(/*/leasehold='Yes')
then 'Leasehold'
else 'Freehold'
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:sequence select=
"if(/*/propertyTypes/propertyType = 'RESIDENTIAL')
then
(if(/*/leasehold='Yes')
then 'Rent'
else 'Buy'
)
else
if(/*/leasehold='Yes')
then 'Leasehold'
else 'Freehold'
"/>
</xsl:template>
</xsl:stylesheet>
<property id="1011">
<leasehold>No</leasehold>
<freehold>Yes</freehold>
<propertyTypes>
<propertyType>RESIDENTIAL</propertyType>
</propertyTypes>
</property>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select=
"concat(
substring('rent',
1 div boolean(/*[leasehold='Yes'
and
propertyTypes/propertyType = 'RESIDENTIAL'
]
)
),
substring('buy',
1 div not(/*[leasehold='Yes'
and
propertyTypes/propertyType = 'RESIDENTIAL'
]
)
)
)
"/>
</xsl:template>
</xsl:stylesheet>
注意事项:
if(/*/propertyTypes/propertyType = 'RESIDENTIAL')
then
(if(/*/leasehold='Yes')
then 'Rent'
else 'Buy'
)
else
if(/*/leasehold='Yes')
then 'Leasehold'
else 'Freehold'
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:sequence select=
"if(/*/propertyTypes/propertyType = 'RESIDENTIAL')
then
(if(/*/leasehold='Yes')
then 'Rent'
else 'Buy'
)
else
if(/*/leasehold='Yes')
then 'Leasehold'
else 'Freehold'
"/>
</xsl:template>
</xsl:stylesheet>
<property id="1011">
<leasehold>No</leasehold>
<freehold>Yes</freehold>
<propertyTypes>
<propertyType>RESIDENTIAL</propertyType>
</propertyTypes>
</property>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select=
"concat(
substring('rent',
1 div boolean(/*[leasehold='Yes'
and
propertyTypes/propertyType = 'RESIDENTIAL'
]
)
),
substring('buy',
1 div not(/*[leasehold='Yes'
and
propertyTypes/propertyType = 'RESIDENTIAL'
]
)
)
)
"/>
</xsl:template>
</xsl:stylesheet>
如果您决定用长度不同于原始字符串的其他字符串替换特定字符串,只需在上述XPath 1.0表达式中替换这些字符串,就不必担心指定任何长度 Becker的数据处理方法如下:
concat(substring('Rent', 1 div boolean(propertyTypes/propertyType ="RESIDENTIAL" and leasehold="Yes")),
substring('Buy', 1 div boolean(propertyTypes/propertyType ="RESIDENTIAL" and leasehold="No")),
substring('Leasehold', 1 div boolean(propertyTypes/propertyType!="RESIDENTIAL" and leasehold="Yes")),
substring('Freehold', 1 div boolean(propertyTypes/propertyType!="RESIDENTIAL" and leasehold="No")))
今天花了一整天,但对我来说很有用这是Xpath 1.0:
concat(
substring(properties/property[@name="Headline"], 1, string-length(properties/property[@name="Headline"]) * 1),
substring(properties/property[@name="Name"], 1, not(number(string-length(properties/property[@name="Headline"]))) * string-length(properties/property[@name="Name"]))
)
choroba,您可能对一个更通用的XPath 1.0表达式感兴趣,它不需要指定长度(并在我们希望使用不同字符串作为结果时进行修改)。很好的解释。有没有办法将节点的长度添加为$cond?@dan,如前所述,这是不必要的。因此,即使字符串的长度未知或随时间变化,此表达式仍然表示所需的条件求值。是的,可能会涉及字符串的长度,但包含字符串的表达式非常脆弱,并且与长度有关