如何在C#
中生成此XML<?xml version='1.0'?>
<oneshot xmlns='http://www.w3.org/2002/xforms' xmlns:dm='http://mobileforms.foo.com/xforms' xmlns:h='http://www.w3.org/1999/xhtml' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
<dm:form_namespace>Foo</dm:form_namespace>
<Days>6</Days>
<Leave_Type>Option 3</Leave_Type>
</oneshot>
我特意挣扎于xmlns:dm声明。有什么想法吗?
答案 0 :(得分:2)
你最好的选择(阅读:最少量的黑客攻击)可能是一个自定义IXmlSerializable
实现;你可以通过XmlRootAttribute
,XmlElementAttribute
等的组合获得你想要的 part-way ,如下所示:
[Serializable]
[XmlRoot("oneshot")]
public class OneShot
{
[XmlElement("form_namespace", Namespace="http://mobileforms.foo.com/xforms")]
public string FormNamespace {get; set;}
[XmlElement("Days")]
public int Days {get; set;}
[XmlElement("Leave_Type")]
public string LeaveType {get; set;}
这将生成如下内容:
<?xml version="1.0" encoding="utf-16"?>
<oneshot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<form_namespace xmlns="http://mobileforms.foo.com/xforms">Foo</form_namespace>
<Days>6</Days>
<Leave_Type>Option 3</Leave_Type>
</oneshot>
但如果您实施IXmlSerializable
,则可以完全控制:
public class OneShot : IXmlSerializable
{
public string FormNamespace {get; set;}
public int Days {get; set;}
public string LeaveType {get; set;}
#region IXmlSerializable
public void WriteXml (XmlWriter writer)
{
writer.WriteStartElement("oneshot");
writer.WriteAttributeString("xmlns", null, "http://www.w3.org/2002/xforms");
writer.WriteAttributeString("xmlns:dm", null, "http://mobileforms.foo.com/xforms");
writer.WriteAttributeString("xmlns:h", null, "http://www.w3.org/1999/xhtml");
writer.WriteAttributeString("xmlns:xsd", null, "http://www.w3.org/2001/XMLSchema");
writer.WriteElementString("dm:form_namespace", null, FormNamespace);
writer.WriteElementString("Days", Days.ToString());
writer.WriteElementString("Leave_Type", LeaveType);
writer.WriteEndElement();
}
public void ReadXml (XmlReader reader)
{
// populate from xml blob
}
public XmlSchema GetSchema()
{
return(null);
}
#endregion
}
这给了你:
<?xml version="1.0" encoding="utf-16"?>
<OneShot>
<oneshot xmlns="http://www.w3.org/2002/xforms" xmlns:dm="http://mobileforms.foo.com/xforms" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<dm:form_namespace>Foo</dm:form_namespace>
<Days>6</Days>
<Leave_Type>Option 3</Leave_Type>
</oneshot>
</OneShot>
答案 1 :(得分:1)
使用不同命名空间中的节点编写XML的一种方法是使用XmlWriter.WriteElementString的4参数版本以您希望的方式显式指定命名空间和前缀:
var s = new StringWriter();
using (var writer = XmlWriter.Create(s))
{
writer.WriteStartElement("oneshot", "http://www.w3.org/2002/xforms");
writer.WriteElementString("dm", "form_namespace",
"http://mobileforms.foo.com/xforms","Foo");
// pick "http://www.w3.org/2002/xforms" by default for Days node
writer.WriteElementString("Days", "6");
// or you can explicitly specify "http://www.w3.org/2002/xforms"
writer.WriteElementString("Leave_Type",
"http://www.w3.org/2002/xforms", "Option 3");
writer.WriteEndElement();
}
Console.Write(s.ToString());
请注意,您的示例XML定义的前缀多于XML中使用的前缀。如果您的要求是生成“文本相同的XML”(从XML的角度来看相同,但没有必要用相同的文本表示),您可能需要花费更多精力在您需要的位置添加名称空间前缀和xmlns属性。
注意2:首先创建XML对象(XDocument用于现代/ LINQ方式,或XmlDocument如果你更喜欢DOM)可能更容易。
答案 2 :(得分:0)
尝试使用.NET 4.0 +程序集System.Xaml。
中的XAML序列化程序您可能需要添加属性以将属性标记为内容而不是XML属性。
答案 3 :(得分:0)
谢谢,大家,求助!这是上述两个答案的组合,它为我做了。我将设置一个提出IXmlSerializable方法的方法,因为这是解决方案的主要部分。
我必须在类名上声明XMLRoot标记,删除WriteStartElement和WriteEndElement,然后使用四参数声明。
这是最终有效的课程:
[Serializable]
[XmlRoot("oneshot")]
public class LeaveRequestPush : IXmlSerializable
{
public string FormNamespace { get; set; }
public int Days { get; set; }
public string LeaveType { get; set; }
#region IXmlSerializable
public void WriteXml(XmlWriter writer)
{
writer.WriteElementString("dm", "form_namespace", "http://mobileforms.devicemagic.com/xforms", FormNamespace);
writer.WriteElementString("Days", Days.ToString());
writer.WriteElementString("Leave_Type", LeaveType);
}
}
public void ReadXml (XmlReader reader)
{
// populate from xml blob
}
public XmlSchema GetSchema()
{
return(null);
}
再次感谢所有人的共同努力。我不会自己拿这个!
答案 4 :(得分:0)
这段代码可以解决问题!
public void WriteXml(XmlWriter writer)
{
const string ns1 = "http://firstline.com/";
const string xsi = "http://www.w3.org/2001/XMLSchema-instance";
writer.WriteStartElement("myRoot", ns1);
writer.WriteAttributeString("SchemaVersion", "1.0");
writer.WriteAttributeString("xmlns", "xsi", "http://www.w3.org/2000/xmlns/", xsi);
writer.WriteAttributeString("xsi", "schemaLocation", xsi, ns1 + " schema1.xs");
writer.WriteStartElement("element1", ns1);
writer.WriteElementString("test1", ns1, "test value");
writer.WriteElementString("test2", ns1, "value 2");
writer.WriteEndElement();
writer.WriteEndElement();//to close classname that has root xml
}
具有多个令人敬畏的命名空间的Xml!
<?xml version="1.0" encoding="utf-16"?>
<myClassNameWhereIXmlSerializableIsImplemented>
<myRoot SchemaVersion="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://firstline.com/ schema1.xs" xmlns="http://firstline.com/">
<element1>
<test1>test value</test1>
<test2>value 2</test2>
</element1>
</myRoot>
</myClassNameWhereIXmlSerializableIsImplemented>
这条线有点令人困惑
writer.WriteAttributeString("xmlns", "xsi", "http://www.w3.org/2000/xmlns/", xsi);
如果您提供随机网址而不是"http://www.w3.org/2000/xmlns/"
,则会失败。 xml中出现的url实际上来自“xsi”变量。
再举一个证明这一点的例子
writer.WriteAttributeString("xml", "base", "http://www.w3.org/XML/1998/namespace", base1);
其中base1 = "<custom url>"
如果你想输出一个像<d:test1>somevalue<\d:test1>
这样的前缀,那么writer.WriteElementString("d","test1", ns1, "somevalue");
如果上面没有定义ns1,那么它将被添加到xml输出中。
但是
<d:test1>
<blah>...
<\d:test1>
需要writer.WriteStartElement("test1", ns1);
时需要使用writer.WriteEndElement();