如何在 XML c# 中的另一个标签内生成标签?

How to generate tags inside another tag in XML c#?

我有一个 class 文件,如下所示:

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>&lt;en&gt;This is English Languages description 
 &lt;/en&gt;&lt;fr&gt;&lt;/fr&gt;</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> 中的许多其他语言是根据我们在数据库中的语言动态生成的。

使用 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")
                })
            }));

        }

与其将 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 的文档表明它应该应用于 XmlElementXmlNode 类型的属性(或相同的数组),但实际上它也适用于 XElement 类型的属性。由于 LINQ-to-XML 比旧的 XmlDocument API 更容易使用,我建议改用它。

  • 在您的问题中,您将 property 显示为 root 的子 class。为了获得您需要的嵌套,它应该是 root 包含的单独 class,而不是 root.

    的子 class
  • 要消除 xsixsd 命名空间(无需进行字符串替换)请参阅 XmlSerializer: remove unnecessary xsi and xsd namespaces .

演示 fiddle here.