我们使用XSD文件published by Agresso 生成我们的XML文件。
我已经使用xsd.exe生成了XSD类,并且可以根据客户的要求成功生成XML文件。
命名空间区域看起来像
<ABWInvoice xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:agrlib="http://services.agresso.com/schema/ABWSchemaLib/2011/11/14" xmlns="http://services.agresso.com/schema/ABWInvoice/2011/11/14">
我通过以下代码实现它:
public static string XmlNamespace<T>(T entity) where T: class
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.OmitXmlDeclaration = true; //removing the encoding, e.g. instead of <?xml version="1.0" encoding="utf-16"?> should be <?xml version="1.0"?>
using (StringWriter sw = new StringWriter())
using (XmlWriter writer = XmlWriter.Create(sw, settings))
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("agrlib", "http://services.agresso.com/schema/ABWSchemaLib/2011/11/14");
ns.Add("xsi","http://www.w3.org/2001/XMLSchema-instance");
XmlSerializer xser = new XmlSerializer(typeof(T));
xser.Serialize(writer, entity, ns);
return sw.ToString();
}
}
我们现在有一个客户,需要添加额外的前缀:“xsi:schemaLocation”,所以它将是
<ABWInvoice xsi:schemaLocation="http://services.agresso.com/schema/ABWInvoice/2011/11/14" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:agrlib="http://services.agresso.com/schema/ABWSchemaLib/2011/11/14" xmlns="http://services.agresso.com/schema/ABWInvoice/2011/11/14">
我在网上找到了很多示例,但它们都添加了 xmlns :schemaLocation而不是 xsi :schemaLocation。此外,我无法修改xsd类,因为它会影响其他客户。
因为我是C#的新手,可以建议如何处理这样的请求吗?
答案 0 :(得分:1)
AFAIK,在代码中执行的唯一方法是添加以下内容:
public class YourRootType
{
[XmlAttribute("schemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string Bar {
get => "http://services.agresso.com/schema/ABWInvoice/2011/11/14";
set { }
}
}
但这会影响所有实例。另一种方法可能是通过类似XSLT的方式添加值,但这很难看。如果您乐意将其保留在代码中,则可以使用条件序列化,即仅在设置时输出;例如:
[XmlAttribute("schemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string Bar { get; set; }
// this pattern is recognized by the serializer itself
public bool ShouldSerializeBar() => !string.IsNullOrWhiteSpace(Bar);
并在运行时为这些客户端设置Bar
到"http://services.agresso.com/schema/ABWInvoice/2011/11/14"
。
另一种选择是使用[XmlAnyAttribute]
:
[XmlAnyAttribute]
XmlAttribute[] AdditionalAttributes { get; set; }
并在运行时附加任意附加属性。但这有点复杂,因为通过C#获取XmlAttribute
实例有点尴尬 - 你需要创建一个DOM等。
我忘了说;在制作xsi:schemaLocation
方面:XmlSerializerNamespaces
所在的位置:
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
ns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
ns.Add("agrlib", "http://services.agresso.com/schema/ABWSchemaLib/2011/11/14");
// etc
并将ns
作为XmlSerializer.Serialize
上的最后一个参数传递。