Xml XSLT:如何检查某个节点在一个父节点中是否都相等
我试图想出一个XSL片段来检查一个类是否所有学生的姓氏都相同。是的,然后(做任何类似的事情)打印“所有姓氏都相同”,否则打印“所有姓氏都不相同” 打印什么真的不重要。我只是想找到正确的逻辑 以下是我的示例XML:Xml XSLT:如何检查某个节点在一个父节点中是否都相等,xml,xslt,Xml,Xslt,我试图想出一个XSL片段来检查一个类是否所有学生的姓氏都相同。是的,然后(做任何类似的事情)打印“所有姓氏都相同”,否则打印“所有姓氏都不相同” 打印什么真的不重要。我只是想找到正确的逻辑 以下是我的示例XML: <root> <class name="Physics"> <student> <firstname>John</firstname> <lastn
<root>
<class name="Physics">
<student>
<firstname>John</firstname>
<lastname>Doe</lastname>
<age>21</age>
</student>
<student>
<firstname>Mary</firstname>
<lastname>Doe</lastname>
<age>21</age>
</student>
<student>
<firstname>Ralph</firstname>
<lastname>Doe</lastname>
<age>21</age>
</student>
</class>
<class name="Math">
<student>
<firstname>John</firstname>
<lastname>Doe</lastname>
<age>21</age>
</student>
<student>
<firstname>Mary</firstname>
<lastname>Doe</lastname>
<age>21</age>
</student>
<student>
<firstname>Tee</firstname>
<lastname>Rex</lastname>
<age>21</age>
</student>
</class>
</root>
约翰
雌鹿
21
玛丽
雌鹿
21
拉尔夫
雌鹿
21
约翰
雌鹿
21
玛丽
雌鹿
21
球座
雷克斯
21
所以,在物理课上,它会打印“所有姓氏都是一样的”。
对于数学课,它会打印“所有姓氏都不一样”
(这不是我真正的XML,因为它无法简化为一个较小的问题,所以我定制了这个XML来表示我的问题)
任何帮助都将不胜感激
问候,,
Shobhit嗯。我对你的问题一无所知,我会这样做:
<xsl:template match="class">
<xsl:choose>
<xsl:when test="
count(student[not(lastname = preceding-sibling::student/lastname)]) = 1
">
<xsl:text>all lastnames are same</xsl:text>
<xsl:when>
<xsl:otherwise>
<xsl:text>all lastnames are not same</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
选择其
不同于同一类中任何前面lastname的所有
节点
在具有所有相同姓氏的类中,它们的计数正好为1(因为第一个学生的姓氏与前面的姓氏不同)。如果计数大于1,则该类中的某些学生具有不同的姓氏
在上述逻辑中,一个班级根本没有学生的情况将被视为
情况。您可能希望以某种方式显式处理这种情况。此样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="student"/>
<xsl:template match="student[1]">all lastnames are same</xsl:template>
<xsl:template match="student[1][lastname != ../student/lastname]" priority="1">all lastnames are not same</xsl:template>
</xsl:stylesheet>
所有姓氏都相同
所有姓氏都不相同
结果:
<root>
<class name="Physics">all lastnames are same</class>
<class name="Math">all lastnames are not same</class>
</root>
所有姓氏都相同
所有姓氏都不相同
注意:节点集比较
编辑:对不起,@name小姐
编辑2:压缩一个。注意@priority以避免错误恢复。此转换:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my"
>
<xsl:output method="text"/>
<xsl:key name="kstudentByName"
match="student" use="lastname"/>
<my:text>
<text> not </text>
</my:text>
<xsl:variable name="vText" select="document('')/*/my:text/*"/>
<xsl:template match="/">
<xsl:variable name="vNumNames" select=
"count(*/*/student[generate-id()
=
generate-id(key('kstudentByName', lastname)[1])
]
)
> 1
"/>
All names are <xsl:value-of select="$vText[$vNumNames]"/> the same.
</xsl:template>
</xsl:stylesheet>
注意键的使用,这使得这种转换比将每个名字与前面所有兄弟姐妹的名字进行二次比较的时间复杂度要有效得多好问题(+1)。请参阅我的答案以获得有效的解决方案。:)伙计们,非常感谢你们的解决方案!我最终采用了托马拉克的方法。虽然other的方法也很好,但Tomalak的解决方案很容易理解和使用。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my"
>
<xsl:output method="text"/>
<xsl:key name="kstudentByName"
match="student" use="lastname"/>
<my:text>
<text> not </text>
</my:text>
<xsl:variable name="vText" select="document('')/*/my:text/*"/>
<xsl:template match="/">
<xsl:variable name="vNumNames" select=
"count(*/*/student[generate-id()
=
generate-id(key('kstudentByName', lastname)[1])
]
)
> 1
"/>
All names are <xsl:value-of select="$vText[$vNumNames]"/> the same.
</xsl:template>
</xsl:stylesheet>
All names are not the same.