1

我有以下需要使用 XSLT 解析的 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>

在上面的 XML 中,PERSON 类型可以按任何顺序出现,我需要如下输出,

<SELECTED>
    <NAME>TEXT</NAME>
</SELECTED>

规则是我们需要根据以下优先级显示名称,A、F、S。

如果类型 A 不存在,则检查类型 F 并在存在时显示名称,否则显示类型 S 名称。

也有可能 B 和 C 等其他类型会出现在输入 XML 中,但我们需要忽略这些类型,只有 A、F 和 S 优先。

在此先感谢,威尔逊。

4

3 回答 3

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使用按优先级类型字符串排序的字符串值与开头的接近程度排序。

于 2012-06-13T12:36:22.610 回答
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>
于 2012-06-13T08:35:24.237 回答
0

您的订单似乎是按字母顺序排列的,但由于您没有这么说,我假设这不是一个可靠的预期。

这个怎么样?

http://www.xmlplayground.com/cMOOBF

如果 IS 的顺序确实可靠地按字母顺序排列,那么最好先对节点进行排序,而不是像我一样使用复杂的谓词。

于 2012-06-13T08:25:12.837 回答