Вложенные условные операторы if else в xpath
у меня есть этот XML-код:
<property id="1011">
<leasehold>No</leasehold>
<freehold>Yes</freehold>
<propertyTypes>
<propertyType>RESIDENTIAL</propertyType>
</propertyTypes>
</property>
и я хочу создать оператор xpath, который совпадает со следующим вложенным блоком псевдокода if-else.
if( propertyTypes/propertyType == 'RESIDENTIAL') {
if( leasehold == 'Yes' ){
return 'Rent'
} else
return 'Buy'
}
} else {
if( leasehold == 'Yes' ){
return 'Leasehold'
} else
return 'Freehold'
}
}
Я видел что-то о методе Беккера, но я не могу следовать ему. XPath на самом деле не моя сильная сторона.
4 ответов
I. В XPath 2.0 это просто переводится как:
if(/*/propertyTypes/propertyType = 'RESIDENTIAL')
then
(if(/*/leasehold='Yes')
then 'Rent'
else 'Buy'
)
else
if(/*/leasehold='Yes')
then 'Leasehold'
else 'Freehold'
проверка на основе XSLT 2.0:
<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>
когда это преобразование применяется к предоставленному XML-документу:
<property id="1011">
<leasehold>No</leasehold>
<freehold>Yes</freehold>
<propertyTypes>
<propertyType>RESIDENTIAL</propertyType>
</propertyTypes>
</property>
выражение XPath вычисляется и результат этой оценки копируется в выходные данные:
Buy
II. XPath 1.0 решение
в XPath 1.0 нет if
оператора.
условный оператор все еще может быть реализован с одним выражением XPath 1.0, но это более сложно, и выражение может быть не слишком читаемым и понятным.
вот общий способ (впервые предложенный Джени Теннисон), чтобы произвести $stringA
, когда условие $cond
is true()
и в противном случае произвести $stringB
:
concat(substring($stringA, 1 div $cond), substring($stringB, 1 div not($cond)))
один из главных достижение этой формулы заключается в том, что она работает для строк любой длины, и никакие длины не должны быть указаны.
объяснение:
здесь мы используем тот факт, что по определению:
number(true()) = 1
и
number(false()) = 0
и
1 div 0 = Infinity
так, если $cond
is false
первый аргумент concat()
выше:
substring($stringA, Infinity)
и это пустая строка, потому что $stringA
имеет конечное длина.
на другой стороне, если $cond
is true()
тогда первый аргумент concat()
выше:
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:
<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>
когда это преобразование применяется к предоставленному XML-документу (выше), вычисляется выражение XPath и результат этой оценки копируется в выходные данные:
buy
Do Примечание:
если вы решите заменить определенные строки другими строками, которые имеют другую длину, чем оригинал, вы просто замените эти строки в приведенном выше выражении XPath 1.0, и вам не придется беспокоиться об указании каких-либо длин.
метод Беккера для ваших данных следующий:
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"]))
)
попробуй такое
if (condition)
then
if (condition) stmnt
else stmnt
else
if (condition) stmnt
else stmnt