我有以下XML,需要使用XSLT解析,
<PERSONS>
<PERSON>
<TYPE>F</TYPE>
<NAME>ABC</NAME>
</PERSON>
<PERSON>
<TYPE>A</TYPE>
<NAME>XYA</NAME>
</PERSON>
<PERSON>
<TYPE>S</TYPE>
<NAME>AFF</NAME>
</PERSON>
<PERSON>
<TYPE>B</TYPE>
<NAME>HHH</NAME>
</PERSON>
</PERSONS>
在上面的XML中,PERSON类型可以按任意顺序排列,我需要输出如下,
<SELECTED>
<NAME>TEXT</NAME>
</SELECTED>
规则是我们需要根据以下优先级显示名称, A,F,S。
如果类型A不存在,请检查类型F并显示名称(如果存在)或显示类型S名称。
也有可能其他类型如B和C将出现在输入XML中,但我们需要忽略这些类型,只有优先权转到A,F和S.
先谢谢, 威尔逊。
答案 0 :(得分:1)
此转化:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pOrder" select="'AFS'"/>
<xsl:template match="/*">
<xsl:for-each select="PERSON[contains($pOrder, TYPE)]">
<xsl:sort select="string-length(substring-before($pOrder, TYPE))" data-type="number"/>
<xsl:if test="position() = 1">
<SELECTED>
<xsl:copy-of select="NAME"/>
</SELECTED>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档:
<PERSONS>
<PERSON>
<TYPE>F</TYPE>
<NAME>ABC</NAME>
</PERSON>
<PERSON>
<TYPE>A</TYPE>
<NAME>XYA</NAME>
</PERSON>
<PERSON>
<TYPE>S</TYPE>
<NAME>AFF</NAME>
</PERSON>
<PERSON>
<TYPE>B</TYPE>
<NAME>HHH</NAME>
</PERSON>
</PERSONS>
生成想要的正确结果:
<SELECTED>
<NAME>XYA</NAME>
</SELECTED>
如果$pOrder
参数已更改,例如至强>:
<xsl:param name="pOrder" select="'SAF'"/>
然后再次产生想要的,正确的结果:
<SELECTED>
<NAME>AFF</NAME>
</SELECTED>
<强>解释强>:
使用Type
的字符串值的紧密度排序到按优先级类型字符串排序的开头。
答案 1 :(得分:0)
您的订单似乎是按字母顺序排列的,但由于您没有说明这一点,我认为这不是一个可靠的期望。
这是怎么回事?
http://www.xmlplayground.com/cMOOBF
如果订单IS确实按字母顺序排列,那么首先对节点进行排序,而不是像我一样使用复杂的谓词。
答案 2 :(得分:0)
假设您的TYPE
按字母顺序排序,您可以使用
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="PERSONS">
<xsl:for-each select="PERSON">
<xsl:sort select="TYPE" order="ascending" />
<xsl:if test="position() = 1">
<SELECTED>
<NAME>
<xsl:value-of select="./NAME" />
</NAME>
</SELECTED>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>