0

I am trying to process a xml schema with Saxon 9 HE (Xslt30Transformer). The xml schema is as below:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://www.proviseconsulting.com/ProcessConfig" 
    xmlns:tns="http://www.proviseconsulting.com/ProcessConfig"
    elementFormDefault="qualified"
    attributeFormDefault="unqualified">
<annotation>
    <documentation>
            This schema defines the structure of the configuration file that  needs to accompany any process workflow in the
            platform. It is mandatory that an instance XML of this schema is present. At the minimum, the 'ProcessConfig'
            element (document element) needs to be present. It is not mandatory that any task configuration is actually
            provided, reason being that a process may have tasks that are not delegate based or the delegates used in the
            process do not require any external configuration.

        NOTE: This schema MUST not be cached as it is updated frequently as more delegate configuration definitions
        are added. The schema would retain backward compatibility.
    </documentation>
</annotation>
<element name="ProcessConfig">
    <annotation>
        <documentation>
            The document element of the process configuration document.
        </documentation>
    </annotation>
    <complexType>
        <sequence>
            <element name="Description" type="string">
                <annotation>
                    <documentation>
                        The description of the process and its configuration. This element is mandatory as there is
                        no other way for a user to understand the configuration and take decision to attach it to the
                        appropriate process instance.
                    </documentation>
                </annotation>
            </element>
            <element name="TaskConfig" minOccurs="0" maxOccurs="unbounded">
                <annotation>
                    <documentation>
                        The element represents an aggregate configuration for a task delegate. It is not  necessary 
                        that the ProcessConfig element contain any of this type of element. The process could be one
                        that does not use any delegates or the delegates used in the process do not require any
                        configuration.
                    </documentation>
                </annotation>
                <complexType>
                    <sequence>
                        <element name="DelegateConfig" minOccurs="0" maxOccurs="1">
                            <annotation>
                                <documentation>
                                    This elements contains the aggregate configuration for a specific delegate. The
                                    exact configuration structure is dependent on the implementation.
                                </documentation>
                            </annotation>
                            <complexType>
                                <choice>
                                    <group ref="tns:imapAttachmentDownloaderGroup"/>
                                    <group ref="tns:customDelegateConfigGroup"/>
                                </choice>

                                <attribute name="delegateId" type="string" use="required">
                                    <annotation>
                                        <documentation>
                                            The identifier of the delegate, while not mandatory, this identifier SHOULD
                                            be the fully qualifies class name of the delegate used with this task.
                                            e.g. com.provise.wfm.delegate.mail.IMAPAttachmentDownloaderDelegate
                                            The id is usually found on the 'delegateId' attribute of the implementation
                                            class.
                                            Example: "com.provise.wfm.delegate.mail.IMAPAttachmentDownloaderDelegate"
                                        </documentation>
                                    </annotation>
                                </attribute>
                                <attributeGroup ref="tns:processVarAttGrp"/>
                            </complexType>
                        </element>
                    </sequence>

                    <attribute name="taskId" use="required">
                        <annotation>
                            <documentation>
                                The id of the task to which this task configuration is attached. The task id MUST be
                                one that is found in the BPMN file for which this document is the configuration.
                                Example: "servicetask5"
                            </documentation>
                        </annotation>
                        <simpleType>
                            <restriction base="string">
                                <pattern value="[A-za-z0-9_]*"/>
                            </restriction>
                        </simpleType>
                    </attribute>
                    <attribute name="taskName" use="required">
                        <annotation>
                            <documentation>
                                The human readable name of the task that is associated with the task id in the BPMN
                                file.
                                Example: "Get User List from AD"
                            </documentation>
                        </annotation>
                        <simpleType>
                            <restriction base="string">
                                <pattern value="[A-Z0-9a-z_]+[A-Z0-9a-z_ ]*"/>
                            </restriction>
                        </simpleType>
                    </attribute>

                </complexType>
            </element>
        </sequence>

        <attribute name="processId" type="string" use="required">
            <annotation>
                <documentation>
                    The identifier of the process as mentioned in the BPMN file.
                    Example: "TestASocProcess"
                </documentation>
            </annotation>
        </attribute>
        <attribute name="processConfigId" use="required" type="tns:uuidType">
            <annotation>
                <documentation>
                    The identifier of this configuration. It is in UUID format.
                    Example: "123e4567-e89b-12d3-a456-426655440000"
                </documentation>
            </annotation>
        </attribute>

    </complexType>
</element>

<group name="imapAttachmentDownloaderGroup">
    <annotation>
        <documentation>
            Configuration block definitions for IMAP attachment downloader delegate. It contains all the configuration
            block definitions that are required to configure the delegate successfully.
        </documentation>
    </annotation>
    <sequence>
        <element name="IMAPConnectorConfig">
            <complexType>
                <attribute name="imapHost" use="required" type="string">
                    <annotation>
                        <documentation>
                            This configuration block deals with the IMAP server name or IP address to where the 
                            connection is to be made to download the attachments.
                            Example: "outlook.office365.com" or "40.100.137.66"
                        </documentation>
                    </annotation>
                </attribute>
                <attribute name="imapPort" use="required" type="int">
                    <annotation>
                        <documentation>
                            The port to use to connect to the server, defaults to 993.
                            Example: "993"
                        </documentation>
                    </annotation>
                </attribute>
                <attribute name="sslEnabled" use="required" type="boolean">
                    <annotation>
                        <documentation>
                            Indicates if the server supports and prefers communication with SSL.
                            Example: "true"
                        </documentation>
                    </annotation>
                </attribute>
                <attribute name="startTLSEnabled" use="required" type="boolean">
                    <annotation>
                        <documentation>
                            If the server supports startTLS, then it would be used.
                            Example: "true"
                        </documentation>
                    </annotation>
                </attribute>
                <attribute name="imapUser" type="string" use="optional">
                    <annotation>
                        <documentation>
                            The user name to connect to IMP server, this is not recommended, the recommended method
                            is to provide reference to a 'credentialId' that is stored in the platform credential
                            store.
                            Example: "firstname.lastname@proviseconsulting.com"
                        </documentation>
                    </annotation>
                </attribute>
                <attribute name="imapPassword" type="string" use="optional">
                    <annotation>
                        <documentation>
                            The password to connect to the IMAP server, not recommended as above.
                            Example: "password@Password_123"
                        </documentation>
                    </annotation>
                </attribute>
                <attribute name="credentialId" type="tns:uuidType" use="optional">
                    <annotation>
                        <documentation>
                            An UUID identifying a credential stored in the credential store of the platform. This is
                            the recommended method of providing any credentials to the process.
                            Example: "a7c5cf43-9573-48a5-9fc6-8b2f264ab538"
                        </documentation>
                    </annotation>
                </attribute>
            </complexType>
        </element>

        <element name="AttachmentConfig" minOccurs="1" maxOccurs="unbounded">
            <annotation>
                <documentation>
                    This configuration block defines the details of the mail and the attachments that need to be
                    downloaded.
                </documentation>
            </annotation>
            <complexType>
                <attribute name="subjectLinePattern" type="string" use="required">
                    <annotation>
                        <documentation>
                            The regular expression patter to select a mail by its subject line.
                            Example: "Subject 0.*"
                        </documentation>
                    </annotation>
                </attribute>
                <attribute name="attachmentFileNamePatterns" type="string" use="required">
                    <annotation>
                        <documentation>
                            This attribute may contain more than one value of regular expression in a space separated
                            string, where each of the expressions are evaluated against each of the attachment file
                            names on the mail. A file name matching any of the listed patters is downloaded.
                            Example: ".*\.csv prefix2_.*\.csv" 
                        </documentation>
                    </annotation>
                </attribute>
                <attribute name="fromAddress" type="string" use="optional">
                    <annotation>
                        <documentation>
                            The from address to be searched on the email and processing if found.
                        </documentation>
                    </annotation>
                </attribute>
                <attributeGroup ref="tns:processVarAttGrp"/>
                <attribute name="saveFileNamePrefix" use="optional">
                    <annotation>
                        <documentation>
                            A prefix that can be added to the file name when it is downloaded. There are 2 special
                            values that can be provided in between '&lt;&gt;' braces, they are:
                            1) UUID - a randomly generated UUID would be substituted
                            2) TIMEMILLIS - the current time in milliseconds would be substituted

                            NOTE: Care must be taken to ensure that the resultant file name does not exceed the
                                  maximum size as supported by the platform.

                            Example: "&lt;UUID&gt;_" - attaches a randomly generated UUID value and '_' before the
                                     file name.
                        </documentation>
                    </annotation>
                    <simpleType>
                        <restriction base="string">
                            <!-- TODO - Do the pattern correctly -->
                            <!-- <pattern value="[A-Z0-9a-z_]*[&lt;UUID&gt;|&lt;TIMEMILLIS&gt;]?[A-Z0-9a-z]*"/> -->
                        </restriction>
                    </simpleType>
                </attribute>
                <attribute name="saveToDir" type="anyURI" use="optional">
                    <annotation>
                        <documentation>
                            If this values is present, the files would be saved in the specific directory. Care
                            should be taken that the directory actually exists in the system. The path needs to
                            be absolute path, using relative paths may lead to unintended behaviour.

                            Example: "D:/etc/csv" or "file://D:/etc/csv"
                        </documentation>
                    </annotation>
                </attribute>
            </complexType>
        </element>
    </sequence>
</group>

<group name="customDelegateConfigGroup">
    <sequence>
        <element name="CustomDelegateConfig">
            <annotation>
                <documentation>
                    This element contains the configuration for a custom delegate. The content model of this is
                    generic and different configuration options can be configured.
                </documentation>
            </annotation>
            <complexType>
                <sequence>
                    <element name="ConfigBlock" minOccurs="1" maxOccurs="unbounded">
                        <complexType>
                            <sequence>
                                <element name="ConfigItem" minOccurs="1" maxOccurs="unbounded">
                                    <complexType>
                                        <attribute name="configName" type="string" use="required"/>
                                        <attribute name="configValue" type="string" use="required"/>
                                    </complexType>
                                </element>
                            </sequence>
                            <attribute name="blockName" type="string" use="required"/>
                            <attributeGroup ref="tns:processVarAttGrp"/>
                        </complexType>
                    </element>
                </sequence>
            </complexType>
        </element>
    </sequence>
</group>

<simpleType name="uuidType">
    <restriction base="string">
        <pattern value="[a-f0-9A-F]{8}-[a-f0-9A-F]{4}-[a-f0-9A-F]{4}-[a-f0-9A-F]{4}-[a-f0-9A-F]{12}"/>
    </restriction>
</simpleType>

<attributeGroup name="processVarAttGrp">
    <attribute name="toProcessVar" use="optional">
        <annotation>
            <documentation>
                This attribute is available on many of the configuration blocks. In general the data exchange
                between tasks in a process is performed through variables set in the execution context of the
                process. May of the task delegates expect inputs and produce outputs to this execution context.
                This attribute refers to the variable to which the task would output on its completion and the
                variable can be used by other tasks downstream.
            </documentation>
        </annotation>
        <simpleType>
            <restriction base="string">
                <pattern value="[A-Z0-9a-z_]*"/>
            </restriction>
        </simpleType>
    </attribute>
    <attribute name="fromProcessVar" use="optional">
        <annotation>
            <documentation>
                Similar to above, if some data needs to be provided to a task from some upstream tasks, then the
                name of the variable is mentioned here. Tasks expect the inputs to be of a specific format.
            </documentation>
        </annotation>
        <simpleType>
            <restriction base="string">
                <pattern value="[A-Z0-9a-z_]*"/>
            </restriction>
        </simpleType>
    </attribute>
</attributeGroup>

The XSL is simple enough as below:

<?xml version="1.0" encoding="UTF-8"?>
<stylesheet version="3.0" 
            xmlns="http://www.w3.org/1999/XSL/Transform"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema"
            xsi:schemaLocation="http://www.w3.org/1999/XSL/Transform 
                                https://www.w3.org/2007/schema-for-xslt20.xsd">
            <output method="text" encoding="utf-8" indent="no"/>
            <strip-space elements="*"/>
<template match="/child::xsi:schema/child::xsi:element">
pppp
<value-of select="attribute::name"/>
    <!-- <apply-templates select="attribute::name"/> -->
</template>

The transformation is working in that I am getting 'pppp' and the name of the attribute. However, it is also printing all the documentation annotation in the schema. the output is as below:

    This schema defines the structure of the configuration file that needs to accompany any process workflow in the
        platform. It is mandatory that an instance XML of this schema is present. At the minimum, the 'ProcessConfig'
        element (document element) needs to be present. It is not mandatory that any task configuration is actually
        provided, reason being that a process may have tasks that are not delegate based or the delegates used in the
        process do not require any external configuration.

        NOTE: This schema MUST not be cached as it is updated frequently as more delegate configuration definitions
        are added. The schema would retain backward compatibility.
pppp
ProcessConfig
Configuration block definitions for IMAP attachment downloader delegate. It    contains all the configuration
            block definitions that are required to configure the delegate successfully.
This configuration block deals with the IMAP server name or IP address to where the 
                            connection is to be made to download the attachments.
                            Example: "outlook.office365.com" or "40.100.137.66"
The port to use to connect to the server, defaults to 993.
                            Example: "993"
Indicates if the server supports and prefers communication with SSL.
                            Example: "true"
If the server supports startTLS, then it would be used.
                            Example: "true"
The user name to connect to IMP server, this is not recommended, the recommended method
                            is to provide reference to a 'credentialId' that is stored in the platform credential
                            store.
                            Example: "firstname.lastname@proviseconsulting.com"

The password to connect to the IMAP server, not recommended as above. Example: "password@Password_123" An UUID identifying a credential stored in the credential store of the platform. This is the recommended method of providing any credentials to the process. Example: "a7c5cf43-9573-48a5-9fc6-8b2f264ab538" This configuration block defines the details of the mail and the attachments that need to be downloaded. The regular expression patter to select a mail by its subject line. Example: "Subject 0." This attribute may contain more than one value of regular expression in a space separated string, where each of the expressions are evaluated against each of the attachment file names on the mail. A file name matching any of the listed patters is downloaded. Example: "..csv prefix2_.*.csv" The from address to be searched on the email and processing if found. A prefix that can be added to the file name when it is downloaded. There are 2 special values that can be provided in between '<>' braces, they are: 1) UUID - a randomly generated UUID would be substituted 2) TIMEMILLIS - the current time in milliseconds would be substituted

                            NOTE: Care must be taken to ensure that the resultant file name does not exceed the
                                  maximum size as supported by the platform.

                            Example: "&lt;UUID&gt;_" - attaches a randomly generated UUID value and '_' before the
                                     file name.

If this values is present, the files would be saved in the specific directory. Care should be taken that the directory actually exists in the system. The path needs to be absolute path, using relative paths may lead to unintended behaviour.

                            Example: "D:/etc/csv" or "file://D:/etc/csv"

This element contains the configuration for a custom delegate. The content model of this is generic and different configuration options can be configured. This attribute is available on many of the configuration blocks. In general the data exchange between tasks in a process is performed through variables set in the execution context of the process. May of the task delegates expect inputs and produce outputs to this execution context. This attribute refers to the variable to which the task would output on its completion and the variable can be used by other tasks downstream. Similar to above, if some data needs to be provided to a task from some upstream tasks, then the name of the variable is mentioned here. Tasks expect the inputs to be of a specific format.

I was expecting only, rest of the text is breaking the downstream processing:

    pppp
    ProcessConfig

Any help would be appreciated. I am slightly new to XSLT 3.0

Ironluca
  • 3,402
  • 4
  • 25
  • 32
  • 1
    Note that in XSLT 3 you can choose your default built-in processing by using e.g. `xsl:mode on-no-match`, see https://www.w3.org/TR/xslt-30/#built-in-rule, so you have a bit more of a choice than in the answers of the duplicate you have been referred to. But in general you have to take the built-in rules into account and override them to suppress text node output. – Martin Honnen Nov 19 '18 at 08:41
  • 1
    @MartinHonnen, thanks for the above. I also appreciate Dr. Kay pointing to the relevant post. In a way, this question is a duplicate. However, from the solution perspective it has another as indicated by MartineHonner. I am now using '' as the child element of the 'stylesheet' element. The output is as expected, there are no other text output. While the post pointed out by Dr. Kay solves it by supplying an template which outputs nothing on a text() node match (I have tried it, it works). Martine Honnern's suggestion is, in my belief more XSLT 3.0 aligned. – Ironluca Nov 19 '18 at 09:33
  • @Ironluca - Maybe you should add a new 3.0 specific answer to the older/duplicate question? – Daniel Haley Nov 19 '18 at 20:56
  • 1
    @DanielHaley thanks for the suggestion, I have appended some 3.0 information to Dimitre's excellent answer on the cited question. – Michael Kay Nov 20 '18 at 11:35

0 Answers0