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='"
"' />
<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='"
"' />
<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>```
我正在使用 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='"
"' />
<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='"
"' />
<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>```