I’m trying a little to use XSLT for purposes other than its intended purpose, namely, to output a report on incorrect XML writing (after checking XSD with a scheme, there are some subtleties that the scheme cannot take into account).

In particular, I encountered a verification problem: If the @A attribute is false, then the @B attribute must be present and has any value (the value itself is checked by the schema).

Made an XSLT template that gets to the desired tag and finds the @A attribute with a value of 'false'. How to check that the @B attribute is missing in this element?

The result of such checks forms an HTML document with a list of errors found.

XSLT looks something like this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:vw="tableview.xsd"> <xsl:output method="html"/> <xsl:template match="/"> <html> <body> <table> <xsl:apply-templates select="vw:template/vw:cells/vw:block"></xsl:apply-templates> </table> </body> </html> </xsl:template> <xsl:template match="text() | @*"> <xsl:apply-templates></xsl:apply-templates> </xsl:template> <xsl:template match="vw:block"> <xsl:for-each select="vw:cell"> <xsl:if test="@readonly='false' and @type = null"> ///Здесь @type = null сам придумал. Не знаю как понять отсутствие атрибута <tr> <td> Атрибут readonly имеет значение <xsl:value-of select="@readonly"/> и атрибут type имеет значение <xsl:value-of select="@type"/> </td> </tr> </xsl:if> </xsl:for-each> </xsl:template> </xsl:stylesheet> 

If you have any comments on the code, I will also listen with pleasure. I get acquainted with XSLT the first day. A part of the "quick start" documentation from msdn.microsoft read, but this is clearly not enough.

    1 answer 1

    Note: for quick testing, I removed the namespace.

    This is done as follows:

     <xsl:template match="block"> <xsl:for-each select="cell"> <xsl:if test="@readonly='false' and @type"> <tr> <td> Атрибут readonly имеет значение <xsl:value-of select="@readonly"/> и атрибут type имеет значение <xsl:value-of select="@type"/> </td> </tr> </xsl:if> <xsl:if test="@readonly='false' and not(@type)"> <tr> <td> Атрибут readonly имеет значение <xsl:value-of select="@readonly"/> и атрибута type нет </td> </tr> </xsl:if> </xsl:for-each> </xsl:template> 

    More correct is to use choose :

     <xsl:template match="block"> <xsl:for-each select="cell"> <xsl:choose> <xsl:when test="@readonly='false' and @type"> <tr> <td> Атрибут readonly имеет значение <xsl:value-of select="@readonly"/> и атрибут type имеет значение <xsl:value-of select="@type"/> </td> </tr> </xsl:when> <xsl:otherwise> <tr> <td> Атрибут readonly имеет значение <xsl:value-of select="@readonly"/> и атрибута type нет </td> </tr> </xsl:otherwise> </xsl:choose> </xsl:for-each> </xsl:template> 

    Even more correct is the use of separate templates for each condition:

     <xsl:template match="block/cell[@type]"> <!-- атрибут @type есть --> <xsl:if test="@readonly='false'"> <tr> <td> Атрибут readonly имеет значение <xsl:value-of select="@readonly"/> и атрибут type имеет значение <xsl:value-of select="@type"/> </td> </tr> </xsl:if> </xsl:template> <xsl:template match="block/cell[not(@type)]"> <!-- атрибута @type нет --> <xsl:if test="@readonly='false'"> <tr> <td> Атрибут readonly имеет значение <xsl:value-of select="@readonly"/> и атрибута type нет </td> </tr> </xsl:if> </xsl:template> 

    Similarly, you can check the readonly attribute value in an xpath expression.