我有一个像下面这样的类文件:
public class property : root
{
public string languages { get; set; }
}
我试图像下面这样生成xml
:
最终输出:
<root>
<property>
--other properties
<languages>
<en>This is English Languages description</en>
<fr></fr>
</languages>
</property>
</root>
这就是我如何试图生成<languages>
标签:
private string GenerateLanguageTag(IList<Languages> languages)
{
string lang = string.Empty;
foreach (var item in languages)
{
lang += "<" + item.IsoLanguageCode + ">" + item.Description + "</" + item.IsoLanguageCode + ">";
}
return lang;
}
输出:
<root>
<property>
--other properties
<languages><en>This is English Languages description
</en><fr></fr></languages>
</property>
</root>
代码:
root root = GetData(data);
XmlSerializer xmlSerializer = new XmlSerializer(typeof(root));
using (StringWriter xmlWriter = new StringWriter())
{
xmlSerializer.Serialize(xmlWriter, root);
value = xmlWriter.ToString();
value = value.Replace(" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"", "");
value = value.Replace(" xmlns:xsd="http://www.w3.org/2001/XMLSchema"", "");
value = value.Replace("utf-16", "ISO-8859-1");
if (File.Exists(filePath))
{
var document = XDocument.Parse(value);
document.Save(filePath);
}
}
更新:
标签"en", "fr"
和<languages></languages>
中的许多其他语言是基于我们在数据库中的语言动态生成的。
与其将languages
声明为string
,不如将其声明为XElement
并标记为[XmlAnyElement("languages")]
。这通知序列化程序,languages
属性的子元素应该作为父元素<property>
的子元素插入。因此,您的数据模型应该如下所示:
public class root
{
public property property { get; set; }
}
public class property
{
[XmlAnyElement("languages")]
public XElement languages { get; set; }
}
你可以这样构建你的模型:
// Your dynamic list of languages & values
var languages = new List<(string IsoLanguageCode, string Description)>
{
("en", "This is English Languages description"),
("fr", ""),
};
var root = new root()
{
property = new()
{
languages = new XElement("languages", languages.Select(l => new XElement(l.IsoLanguageCode, l.Description))),
},
};
指出:
XmlAnyElementAttribute
的文档表明它应该应用于XmlElement
或XmlNode
类型的属性(或相同的数组),但实际上它也适用于XElement
类型的属性。由于LINQ-to-XML比旧的XmlDocument
API更容易使用,我建议使用它。在您的问题中,您将
property
显示为root
的子类。为了获得所需的嵌套,它应该是root
包含的一个单独的类,而不是root
的子类。要消除
xsi
和xsd
命名空间(不需要进行字符串替换),请参见XmlSerializer:删除不必要的xsi和xsd命名空间。
此处演示小提琴
使用Xml Linq:
string header = "<root></root>";
XDocument doc = XDocument.Parse(header);
XElement root = doc.Root;
root.Add( new XElement("property", new object[] {
new XElement("languages", new object[] {
new XElement("en", "This is English Languages description"),
new XElement("fr")
})
}));
}