0

I have an issue with xml/xsl files I have created (I have never worked with XML/XSLT before, so please excuse the quality).

I have been testing the XSLT transforms using IE, EDGE, Firefox and the MS XML Notepad. All nodes produce the correct output except the results_summary/text() node which has the following issue

When I run the XSLT transform in any browser the results_summary/text() node produces no output. When I run the same transform in the Microsoft XML Notepad it produces the correct output for that node.

My second issue is that all the browsers and the XML Notepad all produce the complete XML document at the end of the output document

The source XML was created by a different program I wrote. It converts an NBE structured file into an XML file

I have tested the XML file and it is well formed and valid

Any help would be greatly appreciated, apologies for the length of the code

Below is my XML file is

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="nbescan.xsl"?>
<scan xsi:noNamespaceSchemaLocation="nbescan.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<scan_start>Fri Apr 17 15:29:40 2020</scan_start>
    <host ip="10.10.10.10">
    <host_start>Fri Apr 17 15:29:51 2020</host_start>
        <results>
        <results_subnet>10.10.10</results_subnet>
        <results_ip>10.10.10.10</results_ip>
            <results_summary id="0000108323">
            <port>general/tcp</port>
            <results_severity>Log Message</results_severity>
                The script reports if:
                - a custom scan configuration is in use without having a Port scanner from
                the &apos;Port scanners&apos; family enabled.
                - a port scanner plugin was running into a timeout.
                - a required port scanner (e.g. nmap) is not installed.
                Vulnerability Detection Result:
                https://docs.greenbone.net/GSM-Manual/gos-6/en/performance.html#optimizing-the-scan-performance
                https://docs.greenbone.net/GSM-Manual/gos-6/en/scanning.html?highlight=scanner_plugins_timeout#preference-description
            </results_summary>
            <results_summary id="0000810002">
            <port>general/CPE-T</port>
            <results_severity>Log Message</results_severity>
                This routine uses information collected by other routines about
                CPE identities of operating systems, services and applications detected during the scan.
                Other:
                https://nvd.nist.gov/products/cpe
            </results_summary>
        </results>
    <host_end>Fri Apr 17 16:22:29 2020</host_end>
    </host>
<scan_end>Fri Apr 17 16:22:29 2020</scan_end>
</scan>

XSL File nbescan.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html"/>
<xsl:template match="/">
    <table>
        <tr>
            <td></td>
            <td>Scan Started : </td>
            <td>
                <xsl:value-of select="scan/scan_start"/>
            </td>
            <td>Scan Finished : </td>
            <td>
                <xsl:value-of select="scan/scan_end"/>
            </td>
            <td></td>
        </tr>
    </table>
    <xsl:for-each select="scan/host">
    <table>
        <th>
            <td></td>
            <td></td>
            <td>Host</td>
            <td>
                <xsl:value-of select="@ip"/>
            </td>
            <td></td>
            <td></td>
        </th>
        <tr>
            <td></td>
            <td>Host Started : </td>
            <td>
                <xsl:value-of select="host_start"/>
            </td>
            <td>Host Finished : </td>
            <td>
                <xsl:value-of select="host_end"/>
            </td>
            <td></td>
        </tr>
    </table>

    <table>
        <tr>
            <td></td>
            <td>Results Host : </td>
            <td>
                <xsl:value-of select="results/results_ip"/>
            </td>
            <td>
                <xsl:value-of select="results/results_subnet"/>
            </td>
            <td></td>
        </tr>
    </table>
    <xsl:for-each select="results/results_summary">
    <table>
        <thead>
            <tr>
                <th>Results Summary</th>                
                <th>
                    <xsl:value-of select="@id"/>
                </th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td></td>
                <td>Port</td>
                <td><xsl:value-of select="port"/></td>
                <td>Severity</td>
                <td><xsl:value-of select="results_severity"/></td>
                <td></td>
            </tr>
        </tbody>
    </table>
    <div>
        <xsl:value-of select="text()"/>
    </div>
    <!-- results_sumary for each -->
    </xsl:for-each>
    <!-- host for each -->
    </xsl:for-each>
    <xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>

XSD File nbescan.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="results_summary">
        <xs:complexType mixed="true">
            <xs:sequence>
                <xs:element ref="port"/>
                <xs:element ref="results_severity"/>
            </xs:sequence>
            <xs:attribute name="id" type="xs:string" use="required"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="port" type="xs:string"/>
    <xs:element name="scan">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="scan_start"/>
                <xs:element ref="host"/>
                <xs:element ref="scan_end"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="host">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="host_start"/>
                <xs:element ref="results"/>
                <xs:element ref="host_end"/>
            </xs:sequence>
            <xs:attribute name="ip" type="xs:string" use="required"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="host_start" type="xs:string"/>
    <xs:element name="results_ip" type="xs:string"/>
    <xs:element name="scan_end" type="xs:string"/>
    <xs:element name="results_severity" type="xs:string"/>
    <xs:element name="scan_start" type="xs:string"/>
    <xs:element name="results">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="results_subnet"/>
                <xs:element ref="results_ip"/>
                <xs:element ref="results_summary" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="host_end" type="xs:string"/>
    <xs:element name="results_subnet" type="xs:string"/>
</xs:schema>
10
  • What do you consider the correct output? Perhaps you can reduce your samples to a minimum to demonstrate one problem. Doing <xsl:value-of select="text()"/> in XSLT 1 will output a text node with the contents of the first text child node of the context node which is pure white space in your sample, unless your tool by default strips white space. So perhaps you want to use <xsl:strip-space elements="*"/> if you expect the value-of output the first non-whitespace text node child. Or you use <xsl:apply-templates/> instead of the xsl:value-of. Commented May 23, 2020 at 20:45
  • Then remove that trailing <xsl:apply-templates/> which would output any other text through the built-in templates. Commented May 23, 2020 at 20:46
  • Thanks for the response Martin. The text node data in the XML file is not being output when using edge,firefox or ie, it is output only in the xml notepad editor. I resolved this issue by turning the text nodes into xml elements, and the browsers now output the test. I added an <summary-text> XML element Commented May 24, 2020 at 11:37
  • As a result I changed the <xsl:value-of select="text()"/> to <xsl:value-of select="."/>. I thought the XML standard stated that white space is preserved ? .I tested your <xsl:strip-space elements="*"/>, I changed it to <xsl:strip-space elements="summary_text"/> and that worked thank you Commented May 24, 2020 at 12:14
  • I need to get my head around how text nodes work as distinct from elements and attributes, I obviously do not understand the distinction between white space and non white space in text nodes. My assumption was that the " The script reports if..." node is the first text node and that there would be no difference between the white and non white space characters contained therein. Commented May 24, 2020 at 12:24

1 Answer 1

0

To summarize the findings from the comments, the use of <xsl:apply-templates/> that you had at the end of your template processes all child nodes of the context node with the matching templates which in your case are the built-in ones which copy any text nodes to the result, so removing that <xsl:apply-templates/> should fix the problem of unwanted output.

For the text you want to output, in the XSLT/XPath data model, in the absence of a DTD or schema respectively with an XML parser like the ones in browsers which ignore schemas, any white space between elements results in text nodes with white space only; that way your results_summary element has as its first child node a text node with only white space, then the port element child. And in XSLT 1, using <xsl:value-of select="text()"/> outputs the first selected text child node in document order, so that is why you don't see any text output, that instruction outputs the white space before the port element. So there you need select="text()[normalize-space()]" or some better way using apply-templates to ensure that the text content you want to output is being output.

I can't really tell why you get different results in XML Notepad, it might use the schema to infer a content model but even then, at least in my understanding, as the schema defines a mixed content model, the first white space text node should not be ignored. Either XML Notepad, like many MS XML APIs, by default tries to strip white space, or its schema based parsing is different to what I would expect.

Sign up to request clarification or add additional context in comments.

1 Comment

If I understand you correctly, if I had built templates for each of the complex nodes, <scan> <host> etc I would expect different behavior. I will change the XSLT to test. By changing all XML content to elements I therefore avoided any implementation peculiarities with the use of mixed nodes I also see that you are looking for devs to start using XSLT 3.0. As an exercise I will change the XSLT to conform to XSLT 2.0 and 3.0 out of curiosity. So I may be back with more questions. The beginning of last week was my first attempt at XML so it will take me a little bit of time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.