2012-06-13 297 views
1

选择一个XML节点我有以下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

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

这是怎么回事?

http://www.xmlplayground.com/cMOOBF

如果确实顺序是按字母可靠,倒不如先您的节点进行排序,而不是使用复杂的谓词,因为我有。

+0

我知道你喜欢链接到xmlplayground.com的仅链接答案,但你能明确地发布你的样式表吗?虽然没有反对它的SO政策,但在meta网站上对此事进行了一次讨论,几乎普遍认为这是不好的做法,值得赞成。 –

+0

当然 - 我没有意识到这是JS问题的一大堆问题,我期待JSFiddle会议。有时候只需要代码(对于简单的答案),但有时也很好地展现它的实际效果。在这种情况下,我会开始做这两件事。 – Utkanos

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> 
+0

感谢Filburt的快速反应,但排序不会工作我的情况,因为它有可能来其他类型也' B'和' C'但这些东西我需要忽略,只有优先事项去A,F和S. – Wilz

+0

Filburt,我在问题中也包含了相同的内容,对不起,我没有提过它。 – Wilz

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

+0

这真的很酷! – Filburt

+0

@Filburt:不客气。 –