И. В 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
является 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
равно false
, первый аргумент concat()
выше:
substring($stringA, Infinity)
и это пустая строка, потому что $stringA
имеет конечную длину.
С другой стороны, если $cond
равно 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
Обратите внимание:
Если вы решите заменить определенные строки другими строками, длина которых отличается от исходной, вы просто замените эти строки в приведенном выше выражении XPath 1.0, и вам не придется беспокоиться об указании какой-либо длины.
person
Dimitre Novatchev
schedule
19.10.2012