我是XSLT的新手。 我有一个XML文档,我需要提出xslt来验证XML文档中的某些规则。 XML和xsl文件将在xsltproc工具中使用,输出将是简单的Pass或Fail。
示例XML:
...
<Manager mincount="4" grade="10"...>
<Employee id="1" grade="9" .... />
<Employee id="2" grade="8" .... />
.....
</Manager>
感谢您的帮助! TIA!
答案 0 :(得分:4)
答案 1 :(得分:4)
这是一个提供通过/失败的XSLT 1.0选项。 “失败”中还有其他详细信息,但可以删除。它还将消息输出到stdout和stderr并终止处理。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/Manager">
<xsl:if test="not(count(Employee) >= @mincount)">
<xsl:variable name="vMessage" select="concat('Fail - Number of Employees (',count(Employee),') is not >= to @mincount (',@mincount,').')"/>
<!--stdout-->
<xsl:value-of select="$vMessage" disable-output-escaping="yes"/>
<!--stderr-->
<xsl:message terminate="yes"><xsl:value-of select="$vMessage"/></xsl:message>
</xsl:if>
<xsl:if test="Employee/@grade >= @grade">
<xsl:variable name="vMessage" select="concat('Fail - Employee (id ',Employee[@grade >= ancestor::Manager/@grade][1]/@id,') has a grade (',Employee[@grade >= ancestor::Manager/@grade][1]/@grade,') that is higher than the Manager grade (',@grade,').')"/>
<!--stdout-->
<xsl:value-of select="$vMessage" disable-output-escaping="yes"/>
<!--stderr-->
<xsl:message terminate="yes"><xsl:value-of select="$vMessage"/></xsl:message>
</xsl:if>
<xsl:text>Pass</xsl:text>
</xsl:template>
</xsl:stylesheet>
以下是一些XML /输出示例:
<Manager mincount="1" grade="7" id="28">
<Employee id="6" grade="5"/>
<Employee id="7" grade="1"/>
<Employee id="8" grade="2"/>
<Employee id="3" grade="7"/>
</Manager>
Fail - Employee (id 3) has a grade (7) that is higher than the Manager grade (7).
<Manager mincount="1" grade="7" id="28">
<Employee id="6" grade="5"/>
<Employee id="7" grade="1"/>
<Employee id="8" grade="2"/>
<Employee id="3" grade="6"/>
</Manager>
Pass
<Manager mincount="10" grade="7" id="28">
<Employee id="6" grade="5"/>
<Employee id="7" grade="1"/>
<Employee id="8" grade="2"/>
<Employee id="3" grade="6"/>
</Manager>
Fail - Number of Employees (4) is not >= to @mincount (10).
答案 2 :(得分:1)
这是一个XSLT,它检查mincount值与Employee的实际出现次数。请注意,使用了xsl:function,因此这需要XSLT 2.0。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:custom="http://localhost:8080/customFunctions" exclude-result-prefixes="custom">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:function name="custom:checkMgr">
<xsl:param name="mgr"/>
<xsl:choose>
<xsl:when test="$mgr/@mincount > count($mgr/Employee)">false</xsl:when>
<xsl:when test="count($mgr/Employee[number(@grade) >= number($mgr/@grade)]) > 0">false</xsl:when>
<xsl:otherwise>true</xsl:otherwise>
</xsl:choose>
</xsl:function>
<xsl:template match="/">
<root>
<xsl:apply-templates select="root/Manager"/>
</root>
</xsl:template>
<xsl:template match="Manager">
<mgrCheck>
<xsl:attribute name="id" select="@id"/>
<xsl:attribute name="mincount" select="@mincount"/>
<xsl:attribute name="actual" select="count(Employee)"/>
<xsl:attribute name="grade" select="@grade"/>
<xsl:attribute name="numEmpNoLessGrade" select="count(Employee[number(@grade) >= number(../@grade)])"/>
<xsl:attribute name="OK" select="custom:checkMgr (.)"/>
</mgrCheck>
</xsl:template>
</xsl:stylesheet>
应用于以下输入时:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Manager mincount="4" grade="10" id="26">
<Employee id="1" grade="9"/>
<Employee id="2" grade="8"/>
</Manager>
<Manager mincount="1" grade="10" id="27">
<Employee id="3" grade="9"/>
<Employee id="4" grade="8"/>
<Employee id="5" grade="4"/>
</Manager>
<Manager mincount="1" grade="7" id="28">
<Employee id="6" grade="8"/>
<Employee id="7" grade="7"/>
<Employee id="8" grade="6"/>
<Employee id="9" grade="9"/>
</Manager>
<Manager mincount="3" grade="9" id="29">
<Employee id="10" grade="9"/>
<Employee id="11" grade="8"/>
<Employee id="12" grade="7"/>
</Manager>
</root>
结果是:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<mgrCheck id="26" mincount="4" actual="2" grade="10" numEmpNoLessGrade="0" OK="false"/>
<mgrCheck id="27" mincount="1" actual="3" grade="10" numEmpNoLessGrade="0" OK="true"/>
<mgrCheck id="28" mincount="1" actual="4" grade="7" numEmpNoLessGrade="3" OK="false"/>
<mgrCheck id="29" mincount="3" actual="3" grade="9" numEmpNoLessGrade="1" OK="false"/>
</root>
XSLT 1.0中的替代方案可能如下:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<root>
<xsl:apply-templates select="root/Manager"/>
</root>
</xsl:template>
<xsl:template match="Manager">
<mgrCheck>
<id><xsl:value-of select="@id"/></id>
<mincount><xsl:value-of select="@mincount"/></mincount>
<actual><xsl:value-of select="count(Employee)"/></actual>
<grade><xsl:value-of select="@grade"/></grade>
<numEmpNoLessGrade><xsl:value-of select="count(Employee[@grade >= ../@grade])"/></numEmpNoLessGrade>
<OK>
<xsl:choose>
<xsl:when test="@mincount > count(Employee)">false</xsl:when>
<xsl:when test="count(Employee[@grade >= ../@grade]) > 0">false</xsl:when>
<xsl:otherwise>true</xsl:otherwise>
</xsl:choose>
</OK>
</mgrCheck>
</xsl:template>
</xsl:stylesheet>
结果
<?xml version="1.0" encoding="UTF-8"?>
<root>
<mgrCheck>
<id>26</id>
<mincount>4</mincount>
<actual>2</actual>
<grade>10</grade>
<numEmpNoLessGrade>0</numEmpNoLessGrade>
<OK>false</OK>
</mgrCheck>
<mgrCheck>
<id>27</id>
<mincount>1</mincount>
<actual>3</actual>
<grade>10</grade>
<numEmpNoLessGrade>0</numEmpNoLessGrade>
<OK>true</OK>
</mgrCheck>
<mgrCheck>
<id>28</id>
<mincount>1</mincount>
<actual>4</actual>
<grade>7</grade>
<numEmpNoLessGrade>3</numEmpNoLessGrade>
<OK>false</OK>
</mgrCheck>
<mgrCheck>
<id>29</id>
<mincount>3</mincount>
<actual>3</actual>
<grade>9</grade>
<numEmpNoLessGrade>1</numEmpNoLessGrade>
<OK>false</OK>
</mgrCheck>
</root>