C# XAttribute生成假前缀

C# XAttribute生成假前缀,c#,linq-to-xml,prefix,xattribute,C#,Linq To Xml,Prefix,Xattribute,我正在尝试使用LINQtoXML生成一段xml数据 XNamespace xsins = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance"); XAttribute xsiniltrue = new XAttribute(xsins+"Exists", "true"); XElement elem = new XElement("CustomerRecord", xsiniltrue); 这会在运行时为xsins生成前缀,它们

我正在尝试使用LINQtoXML生成一段xml数据

XNamespace xsins = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance");
XAttribute xsiniltrue = new XAttribute(xsins+"Exists", "true");
XElement elem = new XElement("CustomerRecord", xsiniltrue);
这会在运行时为xsins生成前缀,它们看起来是假的

<Fragment>
    <CustomerRecord p5:Exists="true" xmlns:p5="w3.org/2001/XMLSchema-instance"; /> 
</Fragment> 
<Fragment> 
    <CustomerRecord p3:Exists="false" xmlns:p3="w3.org/2001/XMLSchema-instance"; /> 
</Fragment>
我终于破解了它(至少我希望如此),下面这篇文章解决了我的问题

using (var writer = XmlWriter.Create(fullPath, settings))
{
    writer.WriteStartDocument(true);
    writer.WriteStartElement(string.Empty, "Company", "urn:schemas-company");
    writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
    writer.WriteStartElement(string.Empty, "Add", "urn:schemas-company");
    foreach (var qx in fragments)
    {
        qx.SetAttributeValue(XNamespace.Xmlns + "xsi", xsins.ToString());
        qx.WriteTo(writer);
    }
    writer.WriteEndElement();
    writer.WriteEndElement();
    writer.WriteEndDocument();
}

您希望控制输出的XML前缀

基本上,您只需要将
xml:xsi
添加到根节点,其余部分由linqtoxml负责

请注意,当您进入真正复杂的示例时,它往往会崩溃,但在这种情况下它应该可以工作

编辑:

要删除无关属性,只需手动操作即可:

foreach(var element in root.Descendents())
{
    foreach (var attribute in element.Attributes())
    {
        if (attribute.Name.Namespace == XNamespace.Xmlns)
           attribute.Remove();
    }
}
注意上面的内容很粗糙,我手头没有XML项目

编辑:

我不确定您的输入是什么,但下面是一个硬编码预期输出的示例:

var xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance");
var fragment =
      new XElement("Fragment",
                   new XAttribute(XNamespace.Xmlns + "p5", xsi.ToString()),
                   new XElement("CustomerRecord",
                                new XAttribute(xsi + "Exists", "true")),
                   new XElement("CustomerRecord",
                                new XAttribute(xsi + "Exists", "false")));

我对它进行了测试,它的输出与您要求的完全相同(我在F#中进行了测试,如果出现语法错误,那么很抱歉)

我正在尝试将片段合并在一起。每个片段都有自己的前缀。我试图引入常量前缀,以便在文档级别定义名称空间,而不是对所有片段中的每个元素都定义名称空间。@droidlooms:您仍然可以将名称空间放在根位置,它应该适用于较低的值。如果名称空间已经在较低级别定义,您可以将其删除,尽管自动删除可能会很困难。您知道如何合并这两个名称空间,如果每个片段都有不同的前缀,为什么对您有关系,只要名称空间是相同的?这将是有趣的,看看有多少文件大小的变化,一旦你'修复'这一点。这也将是有趣的,看看有多少时间花在“修复”这一点。
foreach(var element in root.Descendents())
{
    foreach (var attribute in element.Attributes())
    {
        if (attribute.Name.Namespace == XNamespace.Xmlns)
           attribute.Remove();
    }
}
var xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance");
var fragment =
      new XElement("Fragment",
                   new XAttribute(XNamespace.Xmlns + "p5", xsi.ToString()),
                   new XElement("CustomerRecord",
                                new XAttribute(xsi + "Exists", "true")),
                   new XElement("CustomerRecord",
                                new XAttribute(xsi + "Exists", "false")));