在不修改C#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

我们使用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.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)