【问题标题】:XAttribute generates bogus prefixXAttribute 生成虚假前缀
【发布时间】:2013-03-11 15:49:00
【问题描述】:

我正在尝试使用 linq to xml 生成一段 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>

合并为

<Fragment xmlns:p5="w3.org/2001/XMLSchema-instance";  >
    <CustomerRecord p5:Exists="true" /> 
    <CustomerRecord p5:Exists="false" /> 
</Fragment>

也试过用XMLWriter,

XNamespace xsins = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance");

using (var writer = XmlWriter.Create(fullPath, settings))
{
    writer.WriteStartDocument(true);
    writer.WriteStartElement(string.Empty, "Company", "urn:schemas-company");
    //writer.WriteAttributeString(xsins.GetName("xsi"), "http://www.w3.org/2001/XMLSchema-instance");

    writer.WriteStartElement(string.Empty, "Add", "urn:schemas-company");
    foreach (var qx in resultXMLs)
    {
        qx.WriteTo(writer);
    }

    writer.WriteEndElement();
    writer.WriteEndElement();
    writer.WriteEndDocument();
}

我终于破解了(至少我希望如此),下面的部分解决了我的问题

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();
}

【问题讨论】:

    标签: c# linq-to-xml prefix xattribute


    【解决方案1】:

    您想控制输出的 XML 前缀。 For reference an MSDN site

    基本上,您只需将xml:xsi 添加到您的根节点,Linq to XML 应该会负责其余的工作。

    请注意,当您处理非常复杂的示例时,它往往会崩溃,但在这种情况下应该可以工作。

    编辑:

    要删除无关的属性,您可以简单地手动完成:

    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:您仍然可以将命名空间放在根目录下,它应该适用于较低的值。如果名称空间已在较低级别定义,则可以将其删除,尽管自动执行此操作可能很困难。
    • 知道如何合并这两个,w3.org/2001/XMLSchema-instance" /> w3.org/2001/XMLSchema-instance" />
    • 如果每个片段都有不同的前缀,只要命名空间相同,为什么对你很重要?
    • 看看“修复”这个问题后文件大小会发生多大变化会很有趣。看看“修复”这个问题花费了多少时间也会很有趣。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-09
    • 2012-08-13
    • 2020-11-12
    • 1970-01-01
    • 1970-01-01
    • 2014-12-09
    相关资源
    最近更新 更多