У меня есть XML-документ, который может содержать эквивалентные элементы, не являющиеся родственниками, в разных пространствах имен. Я хочу получить значение с наивысшим приоритетом из предоставленного мной списка.
например
<ns1:thing>
<ns1:info>
<ns1:title>Some title</ns1:title>
</ns1:info>
<ns2:metadata>
<ns2:mainTitle>Main title</ns2:mainTitle>
<ns2:altTitle>Alt title</ns2:altTitle>
</ns2:metadata>
...
Я хочу выбрать один из них и вывести его значение, но все эти элементы являются необязательными, поэтому мне нужно будет просмотреть список и найти каждый из них или, возможно, более XSLT-подобных, попытаться применить их последовательно, а затем попробовать следующий, если элемент не может быть найден?
Список приоритетов может быть, скажем, ns2:metadata/ns2:mainTitle
> ns1:info/ns1:title
> ns2:metadata/ns2:altTitle
> "Fallback"
, что при наличии всех дополнительных элементов, как указано выше, приведет к:
<html:title>Main title</html:title>
Я могу использовать только XSLT 1.0 (xsltproc
).
В XSLT / XPath 2 или более поздних версиях легко просто предоставить последовательность (ns2:metadata/ns2:mainTitle, ns1:info/ns1:title, ns2:metadata/ns2:altTitle, 'Fallback')
, а затем взять первый (ns2:metadata/ns2:mainTitle, ns1:info/ns1:title, ns2:metadata/ns2:altTitle, 'Fallback')[1]
для выбора на основе первого доступного элемента.
В XSLT 1 это сложнее выразить компактно и элегантно, возможно, вы сможете жить с жестко запрограммированным xsl:choose
:
<xsl:choose>
<xsl:when test = "ns2:metadata/ns2:mainTitle">
<xsl:value-of select = "ns2:metadata/ns2:mainTitle"/>
</xsl:when>
<xsl:when test = "ns1:info/ns1:title">
<xsl:value-of select = "ns1:info/ns1:title"/>
</xsl:when>
<xsl:when test = "ns2:metadata/ns2:altTitle">
<xsl:value-of select = "ns2:metadata/ns2:altTitle"/>
</xsl:when>
<xsl:otherwise>Fallback</xsl:otherwise>
</xsl:choose>
возможно, завернутый в вызываемый или применимый (возможно, использующий режим) шаблон.