XML 使用 C# 验证然后转换

XML Validation Then Transformation With C#

我正在使用 c# 控制台程序读取 CSV 文件并将其转换为中间 XML 文件。我想根据 XSD 验证 XML,然后如果它有效则执行另一个转换。问题是,我只能验证我是否在生成的中间文件中包含 "xmlns=urn:employee-schema" 条目,并且只有在我包含 "xmlns:ch=urn:employee-schema" 条目时才能进行转换。拥有这两个条目会阻止验证和转换。

相关代码为:

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());
    }
}

employee.xsd 文件:

<?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>

此 XML 将验证但不转换:

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

此 XML 将转换但不验证:

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

这是转换 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>

感谢@michael.hor257k 为我指明了正确的方向。具体来说,我需要将转换 XSLT 更改为:

<?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>

以下同时验证和转换:

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