0

Using a c# console program I am reading a CSV file and converting it into an intermediate XML file. I want to validate the XML against an XSD and then if it is valid perform another transformation. The problem is, I am only able to validate if I include a "xmlns=urn:employee-schema" entry in the generated intermediate file and can only transform if I include "xmlns:ch=urn:employee-schema" entry. Having both entries prevents both validation and transformation.

The relevant code is:

static void Transform(string inputFile, string transformFile, string outputFile)
{
    XslCompiledTransform xslTrans = new XslCompiledTransform(true);
    XsltSettings xsltSettings = new XsltSettings(true, false);

    XmlSchemaSet schemaSet = new XmlSchemaSet();
    schemaSet.Add("urn:employee-schema", "employee.xsd");

    XmlSchema compiledSchema = null;
    foreach (XmlSchema schema in schemaSet.Schemas())
    {
        compiledSchema = schema;
    }

    XmlReaderSettings settings = new XmlReaderSettings();
    settings.Schemas.Add(compiledSchema);

    XmlReader reader = XmlReader.Create(transformFile, settings);
    xslTrans.Load(reader, xsltSettings, null);
    xslTrans.Transform(inputFile, outputFile);
}

static void Validate(string inputFile)
{
    XmlSchemaSet schemaSet = new XmlSchemaSet();
    schemaSet.Add("urn:employee-schema", "employee.xsd");

    XmlSchema compiledSchema = null;
    XmlReaderSettings settings = new XmlReaderSettings();
    foreach (XmlSchema schema in schemaSet.Schemas())
    {
        compiledSchema = schema;
    }

    settings.Schemas.Add(compiledSchema);
    settings.ValidationType = ValidationType.Schema;
    settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
    settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
    settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
    settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);

    using (XmlReader reader = XmlReader.Create(inputFile, settings)) 
    {
        while (reader.Read());
    }
}

The employee.xsd file:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns="urn:employee-schema"
    xmlns:ch="urn:employee-schema"
    elementFormDefault="qualified"
    targetNamespace="urn:employee-schema">

 <xs:element name="employees" type="employeesType" />

 <xs:complexType name="employeesType">
  <xs:sequence maxOccurs="unbounded">
   <xs:element name="employee"  type="employeeType"/>
  </xs:sequence>
 </xs:complexType>

  <xs:complexType name="employeeType">
    <xs:sequence>
      <xs:element minOccurs="1" maxOccurs="1" name="EmployeeNo" type="xs:string" />
      <xs:element minOccurs="1" maxOccurs="1" name="Name" type="xs:string" />
    </xs:sequence>
  </xs:complexType>
</xs:schema>

This XML will validate but not transform:

<?xml version="1.0"?>
<employees xmlns="urn:employee-schema">
  <employee>
    <EmployeeNo>2133654040058</EmployeeNo>
    <Name>Margaret Deakin</Name>
  </employee>
</employees>

This XML will transform but not validate:

<?xml version="1.0"?>
<employees xmlns:ch="urn:employee-schema">
  <employee>
    <EmployeeNo>2133654040058</EmployeeNo>
    <Name>Margaret Deakin</Name>
  </employee>
</employees>

This is the transformation XSLT:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0" >
    <xsl:output encoding="utf-8"  method="text" indent="no"/>
    <xsl:strip-space elements="*" />

    <xsl:variable name='seperator' select='"|"' />
    <xsl:variable name='newline' select='"&#xA;"' />

    <xsl:template match="/employees">
    <xsl:apply-templates />
    </xsl:template>

    <xsl:template match="employee">
    <xsl:text>Employee</xsl:text>
    <xsl:value-of select="$seperator"/>
    <xsl:value-of select="EmployeeNo"/>
    <xsl:value-of select="$seperator"/>
    <xsl:value-of select="Name"/>
    <xsl:value-of select="$newline" />
    </xsl:template>
</xsl:stylesheet>
SteveC
  • 644
  • 7
  • 12
  • 1
    See: https://stackoverflow.com/questions/34758492/xslt-transform-doesnt-work-until-i-remove-root-node/34762628#34762628 – michael.hor257k Oct 08 '19 at 11:12
  • Though the solution was the same, this question differs from the question referred to above in that the symptoms are different, a validation OR a transformation would work but not both. Also, to find the above question, I would have had to know that the problem was just related to XSLT and not the XSD. – SteveC Oct 10 '19 at 08:31

1 Answers1

1

Thanks to @michael.hor257k for pointing me in the right direction. Specifically, I needed to change the transformation XSLT to this:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ch="urn:employee-schema"
    version="1.0" >
    <xsl:output encoding="utf-8"  method="text" indent="no"/>
    <xsl:strip-space elements="*" />

    <xsl:variable name='seperator' select='"|"' />
    <xsl:variable name='newline' select='"&#xA;"' />

    <xsl:template match="/ch:employees">
    <xsl:apply-templates />
    </xsl:template>

    <xsl:template match="ch:employee">
    <xsl:text>Employee</xsl:text>
    <xsl:value-of select="$seperator"/>
    <xsl:value-of select="ch:EmployeeNo"/>
    <xsl:value-of select="$seperator"/>
    <xsl:value-of select="ch:Name"/>
    <xsl:value-of select="$newline" />
    </xsl:template>
</xsl:stylesheet>

And the following both validates and transforms:

<?xml version="1.0"?>
<employees xmlns="urn:employee-schema">
  <employee>
    <EmployeeNo>2133654040058</EmployeeNo>
    <Name>Margaret Deakin</Name>
  </employee>
</employees>```
SteveC
  • 644
  • 7
  • 12