从数据库中导出 XML 文件并在实际列之前获得没有任何属性的干净格式

Posted

技术标签:

【中文标题】从数据库中导出 XML 文件并在实际列之前获得没有任何属性的干净格式【英文标题】:Exported XML file from Database and get clean format without any attributes before actual columns 【发布时间】:2020-04-24 09:01:05 【问题描述】:

我正在创建一个服务,该服务将从使用 WriteXml 的用户存储过程中的 sql server db 生成和导出 xml 文件。它运行成功,但我不希望输出 xml 文件在我想要的实际列之前包含任何 xml 属性。我试过 IgnoreSchema。但是第一行 xml 版本仍然存在,我试图在列之间添加空格。

代码:

public void TEST(string param)
    
     List<Model> list = new List<Model>();

     //this function is for access the db and get the data
     DataSet ds = DAL.Function(param);

     //Export as XML File
     //ds.WriteXml(@"C:\Test\Test.XML", XmlWriteMode.WriteSchema);

输出如下:

<?xml version = "1.0" standalone="yes"?>
<NewDataSet>
  <Table>
    <a> 005 </a>
    <b> 1 </b>
  </Table>
  <Table>
    <a> 006 </a>
    <b> 2 </b>
  </Table>
</NewDataSet>

但我希望它看起来像这样的格式:

  <Table>
    <a> 005 </a>
    <b> 1 </b>
  </Table>

  <Table>
    <a> 006 </a>
    <b> 2 </b>
  </Table>

【问题讨论】:

【参考方案1】:

首先我要指出,格式良好的 XML 文档必须有 only one root element。

在正常情况下,我会说你不应该尝试弄乱System.Xml 命名空间,因为它会变得非常脏。但是让我们再想象一下,我们并不关心性能和可维护性,当然,这纯粹是一个思想实验。那么解决您的问题的一种方法是修改XmlWriter,使其跳过您的NewDataSet 标签:

class MyWriter : XmlTextWriter

    private int Top // this is a pointer to top of internal stack that XmlWriter uses to determine closing tag correspondence
    
        get
        
            FieldInfo top = typeof(XmlTextWriter).GetField("top", BindingFlags.NonPublic | BindingFlags.Instance);
            return (int)top.GetValue(this);
        
    

    public MyWriter(string name, Encoding enc) : base(name, enc) 

    public override void WriteStartElement(string prefix, string localName, string ns)
    
        if (localName == "NewDataSet")  // skip the tag
            MethodInfo PushStack = typeof(XmlTextWriter).GetMethod("PushStack", BindingFlags.NonPublic | BindingFlags.Instance);
            PushStack.Invoke(this, new object[] ); // for internal state tracking to work, we still need to push the stack as if we wrote it out. we'll have to account for that later
            return;
        

        base.WriteStartElement(prefix, localName, ns);
    

    public override void WriteEndElement()
    
        if(Top <= 1) return; // do not attempt to write outermost tag, we already skipped it in the opening counterpart
        base.WriteEndElement();
    

void Main()

    //...your code here

    var writer = new MyWriter(@"C:\Test\Test.XML", Encoding.UTF8); // instantiate your own writerm
    ds.WriteXml(writer, XmlWriteMode.IgnoreSchema); // and use it instead of stock standard

如您所见,问题是,XmlWriter 没有公开它工作所需的一些方法和属性,所以我不得不使用反射来调用它们。此外,通过将某些数据结构保留在类内部来获取它们变得非常困难(作为练习,尝试使用上述技术获取 TagInfo[] stack 字段,看看会发生什么)。

然而,这应该会给你你想要的输出。

【讨论】:

以上是关于从数据库中导出 XML 文件并在实际列之前获得没有任何属性的干净格式的主要内容,如果未能解决你的问题,请参考以下文章

如何从phpmyadmin中的数据库中的特定表中导出特定列

从访问中导出嵌套的 XML 文件。需要带有节点的XML文件[重复]

(编辑)如何在Windows中导出模板专业化,并在cpp文件中声明源

从 ZIP 存档中导出文件列表而不解压缩

从一个 GET 请求中导出输入查询并在单独的请求中使用它们

如何从时间分析器仪器中导出 cpu 使用情况