在不修改C#XSD类的情况下,为XML序列化添加前缀和名称空间
我们使用XSD文件, 生成我们的XML文件 我已经使用XSD.exe生成了和XSD类,并且可以根据客户的请求成功生成XML文件 名称空间区域看起来像在不修改C#XSD类的情况下,为XML序列化添加前缀和名称空间,c#,xml,xsd,xml-namespaces,prefix,C#,Xml,Xsd,Xml Namespaces,Prefix,我们使用XSD文件, 生成我们的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.c
<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();
}
}
公共静态字符串XmlNamespace(T实体),其中T:class
{
XmlWriterSettings=新的XmlWriterSettings();
settings.Indent=true;
settings.OmitXmlDeclaration=true;//删除编码,例如,应删除而不是
使用(StringWriter sw=new StringWriter())
使用(XmlWriter=XmlWriter.Create(软件,设置))
{
XmlSerializerNamespaces ns=新的XmlSerializerNamespaces();
添加(“agrlib”http://services.agresso.com/schema/ABWSchemaLib/2011/11/14");
添加(“xsi”http://www.w3.org/2001/XMLSchema-instance");
XmlSerializer xser=新的XmlSerializer(typeof(T));
序列化(writer、entity、ns);
返回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">
我在web上找到了许多示例,但它们都添加了xmlns:schemaLocation,而不是xsi:schemaLocation。我也不能修改xsd类,因为它会影响其他客户
由于我是C的新手,请告诉我如何处理这样的请求,好吗?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#获得xmltattribute
实例有点尴尬——您需要创建一个DOM等等
我忘了说;就制作
xsi:schemaLocation
:这就是xmlserializernamespace
的用武之地:
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
对于C#新手来说太复杂了,但现在就开始吧!我唯一不明白的是,在您的示例中,Bar如何与schemaLocation关联。你能解释一下吗?非常感谢您的第三方要求您不要添加名称空间或前缀或类似的内容;他们要求您在名称空间中添加一个本地名为“schemaLocation”的属性http://www.w3.org/2001/XMLSchema-instance
,值为http://services.agresso.com/schema/ABWInvoice/2011/11/14“
-最好还有一个与"http://www.w3.org/2001/XMLSchema-instance“
名称空间,其效果是您的属性也可以通过“xsi:schemaLocation”
引用。栏上的[xmldattribute]
(1/2)(2/2)定义名称和命名空间;XmlSerializerNamespaces
定义了一组命名空间别名,值来自所示的代码。这就是它们之间的联系。这是否回答了问题?还是仍然不清楚?是的,确实如此!Ta。抱歉,我没有足够的声誉将您的答案标记为有用(至少需要15个)。谢谢你,@Marc。这真的很管用。我可以再问你两个问题吗:1)当我添加了ns.添加(“,”);
就像你的例子一样,所有元素都有一个q1前缀,例如
我必须添加其他东西吗?(1/2)