自动从外部文件替换表

2024-03-22

我正在尝试使用外部 XML 文件替换大型(~300 MB)XML 文件中的多个表。

大约有 30,000 个表,并且有 23,000 个 XML 文件,因为某些表未更改。

例如,如果我有:

<?xml version="1.0" encoding="UTF-8"?>
<INI>
   <TABLE name="People">
      <ROW>
         <ID>1</ID>
         <Name><![CDATA[Bob]]></Name>
      </ROW>
   </TABLE>
   <TABLE name="Animals">
      <ROW>
         <ID>1</ID>
         <Name><![CDATA[Golden]]></Name>
      </ROW>
   </TABLE>
</INI>

我会有名为People.xml and Animals.xml应该更换。

If People.xml were:

   <TABLE name="People">
      <ROW>
         <ID>1</ID>
         <Name><![CDATA[Mary]]></Name>
      </ROW>
      <ROW>
         <ID>2</ID>
         <Name><![CDATA[Bob]]></Name>
      </ROW>
      <ROW>
         <ID>3</ID>
         <Name><![CDATA[Dan]]></Name>
      </ROW>
   </TABLE>

那么主要的大型 XML 文件将变成:

<?xml version="1.0" encoding="UTF-8"?>
<INI>
   <TABLE name="People">
      <ROW>
         <ID>1</ID>
         <Name><![CDATA[Mary]]></Name>
      </ROW>
      <ROW>
         <ID>2</ID>
         <Name><![CDATA[Bob]]></Name>
      </ROW>
      <ROW>
         <ID>3</ID>
         <Name><![CDATA[Dan]]></Name>
      </ROW>
   </TABLE>
   <TABLE name="Animals">
      <ROW>
         <ID>1</ID>
         <Name><![CDATA[Golden]]></Name>
      </ROW>
   </TABLE>
</INI>

然后同样的Animals.xml.

我尝试过调查String.Split(),但我找不到这样的方法。

任何帮助表示赞赏。提前致谢!


你能做的就是采用流式传输的基本逻辑XmlReader to an XmlWriter摘自马克·福塞尔的文章组合 XmlReader 和 XmlWriter 类以进行简单的流式转换 https://web.archive.org/web/20160214201608/https://blogs.msdn.com/b/mfussell/archive/2005/02/12/371546.aspx将一个 XML 文件的内容修补到另一个 XML 文件中:

public abstract class XmlStreamingEditorBase
{
    readonly XmlReader reader;
    readonly XmlWriter writer;
    readonly Predicate<XmlReader> shouldTransform;

    public XmlStreamingEditorBase(XmlReader reader, XmlWriter writer, Predicate<XmlReader> shouldTransform)
    {
        this.reader = reader;
        this.writer = writer;
        this.shouldTransform = shouldTransform;
    }

    protected XmlReader Reader { get { return reader; } }

    protected XmlWriter Writer { get { return writer; } }

    public void Process()
    {
        while (Reader.Read())
        {
            if (Reader.NodeType == XmlNodeType.Element)
            {
                if (shouldTransform(Reader))
                {
                    EditCurrentElement();
                    continue;
                }
            }
            Writer.WriteShallowNode(Reader);
        }
    }

    protected abstract void EditCurrentElement();
}

public class XmlStreamingEditor : XmlStreamingEditorBase
{
    readonly Action<XmlReader, XmlWriter> transform;

    public XmlStreamingEditor(XmlReader reader, XmlWriter writer, Predicate<XmlReader> shouldTransform, Action<XmlReader, XmlWriter> transform)
        : base(reader, writer, shouldTransform)
    {
        this.transform = transform;
    }

    protected override void EditCurrentElement()
    {
        using (var subReader = Reader.ReadSubtree())
        {
            transform(subReader, Writer);
        }
    }
}

public class XmlStreamingPatcher
{
    readonly XmlReader patchReader;
    readonly XmlReader reader;
    readonly XmlWriter writer;
    readonly Predicate<XmlReader> shouldPatchFrom;
    readonly Func<XmlReader, XmlReader, bool> shouldPatchFromTo;
    bool patched = false;

    public XmlStreamingPatcher(XmlReader reader, XmlWriter writer, XmlReader patchReader, Predicate<XmlReader> shouldPatchFrom, Func<XmlReader, XmlReader, bool> shouldPatchFromTo)
    {
        if (reader == null || writer == null || patchReader == null || shouldPatchFrom == null || shouldPatchFromTo == null)
            throw new ArgumentNullException();
        this.reader = reader;
        this.writer = writer;
        this.patchReader = patchReader;
        this.shouldPatchFrom = shouldPatchFrom;
        this.shouldPatchFromTo = shouldPatchFromTo;
    }

    public bool Process()
    {
        patched = false;
        while (patchReader.Read())
        {
            if (patchReader.NodeType == XmlNodeType.Element)
            {
                if (shouldPatchFrom(patchReader))
                {
                    var editor = new XmlStreamingEditor(reader, writer, ShouldPatchTo, PatchNode);
                    editor.Process();
                    return patched;
                }
            }
        }
        return false;
    }

    bool ShouldPatchTo(XmlReader reader)
    {
        return shouldPatchFromTo(patchReader, reader);
    }

    void PatchNode(XmlReader reader, XmlWriter writer)
    {
        using (var subReader = patchReader.ReadSubtree())
        {
            while (subReader.Read())
            {
                writer.WriteShallowNode(subReader);
                patched = true;
            }
        }
    }
}

public static class XmlReaderExtensions
{
    public static XName GetElementName(this XmlReader reader)
    {
        if (reader == null)
            return null;
        if (reader.NodeType != XmlNodeType.Element)
            return null;
        string localName = reader.Name;
        string uri = reader.NamespaceURI;
        return XName.Get(localName, uri);
    }
}

public static class XmlWriterExtensions
{
    public static void WriteShallowNode(this XmlWriter writer, XmlReader reader)
    {
        // adapted from http://blogs.msdn.com/b/mfussell/archive/2005/02/12/371546.aspx
        if (reader == null)
            throw new ArgumentNullException("reader");

        if (writer == null)
            throw new ArgumentNullException("writer");

        switch (reader.NodeType)
        {
            case XmlNodeType.Element:
                writer.WriteStartElement(reader.Prefix, reader.LocalName, reader.NamespaceURI);
                writer.WriteAttributes(reader, true);
                if (reader.IsEmptyElement)
                {
                    writer.WriteEndElement();
                }
                break;

            case XmlNodeType.Text:
                writer.WriteString(reader.Value);
                break;

            case XmlNodeType.Whitespace:
            case XmlNodeType.SignificantWhitespace:
                writer.WriteWhitespace(reader.Value);
                break;

            case XmlNodeType.CDATA:
                writer.WriteCData(reader.Value);
                break;

            case XmlNodeType.EntityReference:
                writer.WriteEntityRef(reader.Name);
                break;

            case XmlNodeType.XmlDeclaration:
            case XmlNodeType.ProcessingInstruction:
                writer.WriteProcessingInstruction(reader.Name, reader.Value);
                break;

            case XmlNodeType.DocumentType:
                writer.WriteDocType(reader.Name, reader.GetAttribute("PUBLIC"), reader.GetAttribute("SYSTEM"), reader.Value);
                break;

            case XmlNodeType.Comment:
                writer.WriteComment(reader.Value);
                break;

            case XmlNodeType.EndElement:
                writer.WriteFullEndElement();
                break;

            default:
                Debug.WriteLine("unknown NodeType " + reader.NodeType);
                break;

        }
    }
}

创建实例XmlReader and XmlWriter要从文件中读取和写入 XML,请使用XmlReader.Create(string) https://msdn.microsoft.com/en-us/library/w8k674bf%28v=vs.110%29.aspx and XmlWriter.Create(string) https://msdn.microsoft.com/en-us/library/kcsse48t%28v=vs.110%29.aspx。另外,请务必将大文件流式传输到临时文件中,并仅在编辑完成后替换原始文件。

然后,进行测试:

public static class TestXmlStreamingPatcher
{
    public static void Test()
    {
        string mainXml = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<INI>
   <TABLE name=""People"">
      <ROW>
         <ID>1</ID>
         <Name><![CDATA[Bob]]></Name>
      </ROW>
   </TABLE>
   <TABLE name=""Animals"">
      <ROW>
         <ID>1</ID>
         <Name><![CDATA[Golden]]></Name>
      </ROW>
   </TABLE>
</INI>
";
        string patchXml = @"<TABLE name=""People"">
      <ROW>
         <ID>1</ID>
         <Name><![CDATA[Mary]]></Name>
      </ROW>
      <ROW>
         <ID>2</ID>
         <Name><![CDATA[Bob]]></Name>
      </ROW>
      <ROW>
         <ID>3</ID>
         <Name><![CDATA[Dan]]></Name>
      </ROW>
   </TABLE>
";
        var patchedXml1 = TestPatch(mainXml, patchXml);
        Debug.WriteLine(patchedXml1);
    }

    private static string TestPatch(string mainXml, string patchXml)
    {
        using (var mainReader = new StringReader(mainXml))
        using (var mainXmlReader = XmlReader.Create(mainReader))
        using (var patchReader = new StringReader(patchXml))
        using (var patchXmlReader = XmlReader.Create(patchReader))
        using (var mainWriter = new StringWriter())
        {
            using (var mainXmlWriter = XmlWriter.Create(mainWriter))
            {
                var patcher = new XmlStreamingPatcher(mainXmlReader, mainXmlWriter, patchXmlReader, ShouldPatchFrom, ShouldPatchFromTo);
                patcher.Process();
            }
            return mainWriter.ToString();
        }
    }

    static bool ShouldPatchFrom(XmlReader reader)
    {
        return reader.GetElementName() == "TABLE";
    }

    static bool ShouldPatchFromTo(XmlReader patchReader, XmlReader toReader)
    {
        if (patchReader.GetElementName() != toReader.GetElementName())
            return false;
        string name = patchReader.GetAttribute("name");
        if (string.IsNullOrEmpty(name))
            return false;
        return name == toReader.GetAttribute("name");
    }
}

的输出TestXmlStreamingPatcher.Test()从这个班级是

<?xml version="1.0" encoding="UTF-8"?>
<INI>
   <TABLE name="People">
      <ROW>
         <ID>1</ID>
         <Name><![CDATA[Mary]]></Name>
      </ROW>
      <ROW>
         <ID>2</ID>
         <Name><![CDATA[Bob]]></Name>
      </ROW>
      <ROW>
         <ID>3</ID>
         <Name><![CDATA[Dan]]></Name>
      </ROW>
   </TABLE>
   <TABLE name="Animals">
      <ROW>
         <ID>1</ID>
         <Name><![CDATA[Golden]]></Name>
      </ROW>
   </TABLE>
</INI>

这就是你想要的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自动从外部文件替换表 的相关文章

  • 代码 GetAsyncKeyState(VK_SHIFT) & 0x8000 中的这些数字是什么?它们是必不可少的吗?

    我试图在按下按键的简单动作中找到这些数字及其含义的任何逻辑解释 GetAsyncKeyState VK SHIFT 0x8000 可以使用哪些其他值来代替0x8000它们与按键有什么关系 GetAsyncKeyState 根据文档返回 如果
  • IdentityServer 4 对它的工作原理感到困惑

    我阅读和观看了很多有关 Identity Server 4 的内容 但我仍然对它有点困惑 因为似乎有很多移动部件 我现在明白这是一个单独的项目 它处理用户身份验证 我仍然不明白的是用户如何注册它 谁存储用户名 密码 我打算进行此设置 Rea
  • Text::平衡和多行 xml

    看来我有点失落了 我需要解析一个大的 大约 100 mb 且相当难看的 xml 文件 如果我使用parsefile 它返回错误 文档元素后的垃圾 但它会很乐意解析文件的较小元素 所以我决定将文件分解为元素并解析它们 由于不鼓励使用正则表达式
  • 在 bash 脚本中提取 XML 值 [重复]

    这个问题在这里已经有答案了 我正在尝试从 xml 文档中提取一个值 该文档已作为变量读入我的脚本中 原始变量 data is
  • JNI 将 Char* 2D 数组传递给 JAVA 代码

    我想从 C 代码通过 JNI 层传递以下指针数组 char result MAXTEST MAXRESPONSE 12 12 8 3 29 70 5 2 42 42 在java代码中我写了以下声明 public static native
  • Python 属性和 Swig

    我正在尝试使用 swig 为一些 C 代码创建 python 绑定 我似乎遇到了一个问题 试图从我拥有的一些访问器函数创建 python 属性 方法如下 class Player public void entity Entity enti
  • C# 存档中的文件列表

    我正在创建一个 FileFinder 类 您可以在其中进行如下搜索 var fileFinder new FileFinder new string C MyFolder1 C MyFolder2 new string
  • 在 NaN 情况下 to_string() 可以返回什么

    我使用 VS 2012 遇到了非常令人恼火的行为 有时我的浮点数是 NaN auto dbgHelp std to string myFloat dbgHelp最终包含5008角色 你不能发明这个东西 其中大部分为0 最终结果是 0 INF
  • 为什么这个二维指针表示法有效,而另一个则无效[重复]

    这个问题在这里已经有答案了 这里我编写了一段代码来打印 3x3 矩阵的对角线值之和 这里我必须将矩阵传递给函数 矩阵被传递给指针数组 代码可以工作 但问题是我必须编写参数的方式如下 int mat 3 以下导致程序崩溃 int mat 3
  • 为什么我的单选按钮不起作用?

    我正在 Visual C 2005 中开发 MFC 对话框应用程序 我的单选按钮是 m Small m Medium 和 m Large 它们都没有在我的 m Summary 编辑框中显示应有的内容 可能出什么问题了 这是我的代码 Pizz
  • 检测到严重错误 c0000374 - C++ dll 将已分配内存的指针返回到 C#

    我有一个 c dll 它为我的主 c 应用程序提供一些功能 在这里 我尝试读取一个文件 将其加载到内存 然后返回一些信息 例如加载数据的指针和内存块的计数到 c Dll 成功将文件读取到内存 但在返回主应用程序时 程序由于堆损坏而崩溃 检测
  • WPF DataGridTemplateColumn 组合框更新所有行

    我有这个 XAML 它从 ItemSource 是枚举的组合框中选择一个值 我使用的教程是 http www c sharpcorner com uploadfile dpatra combobox in datagrid in wpf h
  • Unity:通过拦截将两个接口注册为一个单例

    我有一个实现两个接口的类 我想对该类的方法应用拦截 我正在遵循中的建议Unity 将两个接口注册为一个单例 https stackoverflow com questions 1394650 unity register two inter
  • WebBrowser.Print() 等待完成。 。网

    我在 VB NET 中使用 WebBrowser 控件并调用 Print 方法 我正在使用 PDF 打印机进行打印 当调用 Print 时 它不会立即启动 它会等到完成整个子或块的运行代码 我需要确保我正在打印的文件也完整并继续处理该文件
  • OpenGL:仅获取模板缓冲区而没有深度缓冲区?

    我想获取一个模板缓冲区 但如果可能的话 不要承受附加深度缓冲区的开销 因为我不会使用它 我发现的大多数资源表明 虽然模板缓冲区是可选的 例如 排除它以利于获得更高的深度缓冲区精度 但我还没有看到任何请求并成功获取仅 8 位模板缓冲区的代码
  • 我可以在 XSLT 中创建模板吗?

    我想使用 XSLT 从 XML 创建 ASP NET 用户控件 目前我真的把结果一点一点地拼凑起来
  • 将数组作为参数传递

    如果我们修改作为方法内参数传递的数组的内容 则修改是在参数的副本而不是原始参数上完成的 因此结果不可见 当我们调用具有引用类型参数的方法时 会发生什么过程 这是我想问的代码示例 using System namespace Value Re
  • 使用 C 在 OS X 中获取其他进程的 argv

    我想获得其他进程的argv 例如ps 我使用的是在 Intel 或 PowerPC 上运行的 Mac OS X 10 4 11 首先 我阅读了 ps 和 man kvm 的代码 然后编写了一些 C 代码 include
  • 如何减少具有多个单元的 PdfPTable 的内存消耗

    我正在使用 ITextSharp 创建一个 PDF 它由单个 PdfTable 组成 不幸的是 对于特定的数据集 由于创建了大量 PdfPCell 我遇到了内存不足异常 我已经分析了内存使用情况 我有近百万个单元格的 1 2 在这种情况下有
  • 如何使用 C++11 using 语法键入定义函数指针?

    我想写这个 typedef void FunctionPtr using using 我该怎么做呢 它具有类似的语法 只不过您从指针中删除了标识符 using FunctionPtr void 这是一个Example http ideone

随机推荐

  • 使用 NSPersistentStoreCoordinator 的要点是什么?

    在核心数据讲座中斯坦福193P http www stanford edu class cs193p cgi bin drupal iTunes 上的 iPhone 课程 讲师使用 Core Data 编写了一个示例项目 而没有使用NSPe
  • Hibernate二级缓存-打印结果

    我使用 Cache 注释在应用程序中定义了二级缓存 我正在使用 findById 查询 如下所示 long id 4 Company cmp companyDAO findById id 其中 Company 是我从数据库获得的对象 如何检
  • Spring Boot 和 Ehcache - 多 CacheException

    我正在尝试向 springboot 应用程序添加缓存 但遇到了启动过程中引发 org ehcache jsr107 MultiCacheException 异常的问题 我正在使用以下内容 全部通过 Maven pom 文件加载 Spring
  • Python - 什么时候可以使用 os.system() 发出常见的 Linux 命令

    从另一个线程中分离出来 什么时候适合使用 os system 发出 rm rf cd make xterm ls 等命令 考虑到上述命令有模拟版本 make 和 xterm 除外 我假设使用这些内置 python 命令而不是使用 os sy
  • Seaborn:ValueError:调色板='jet'否

    从seaborn运行以下示例docs https seaborn pydata org generated seaborn boxplot html有论据palette jet import seaborn as sns tips sns
  • 金字塔资源:简单的英语

    我一直在阅读对新创建的金字塔应用程序实施授权 和身份验证 的方法 我不断遇到 资源 这个概念 我在应用程序中使用 python couchdb 根本不使用 RDBMS 因此没有 SQLAlchemy 如果我像这样创建一个 Product 对
  • 为什么说malloc()和printf()是不可重入的?

    在 UNIX 系统中我们知道malloc 是不可重入函数 系统调用 这是为什么 相似地 printf 也被认为是不可重入的 为什么 我知道可重入的定义 但我想知道为什么它适用于这些函数 是什么阻止了它们保证可重入 malloc and pr
  • Cassandra 种子节点和连接到节点的客户端

    我对 Cassandra 种子节点以及客户端如何连接到集群有点困惑 我似乎在文档中找不到这一点信息 客户端是否仅包含种子节点列表 并且每个节点委托一个新主机供客户端连接 种子节点是否真的仅用于节点到节点的发现 而不是客户端的特殊节点 每个客
  • 如何捕获发送到模拟的参数?

    有谁知道如何捕获发送到 OCMock 对象的参数 id mock OCMockObject mockForClass someClass NSObject captureThisArgument mock expect foo
  • 如何从 onBind 函数获取尝试绑定我的服务的应用程序包名称或 UID?

    我在一个应用程序中有一个服务 我可以从不同的应用程序访问该服务 当应用程序尝试绑定此服务时 我想知道哪个应用程序正在尝试在 onBind 函数中绑定我的服务 但我无法在 onBind 函数中获取该应用程序的包名称或 UID 是否可以获取尝试
  • 使用 MPJ Express 发送对象

    我是并行编程的新手 我想用 java 来完成它 我想知道是否可以通过 MPI 发送和接收更复杂的对象 我用的是 MPJ Express 然而 每当我想发送一个对象时 我都会收到 ClassCastException MPI Init arg
  • 如何使用 vscode:// 链接打开文件

    我想像phpstorm一样使用vscode ide链接 我知道我们可以phpstorm open file filepath line line 如何使用vscode达到同样的效果 多谢 这个链接 vscode file file line
  • SwiftUI 在 NavigationLink 视图中隐藏 TabView 栏

    我为每个选项卡项目都有一个 TabView 和单独的 NavigationView 堆栈 它工作得很好 但是当我打开任何 NavigationLink 时 TabView 栏仍然显示 我希望每当我单击任何导航链接时它就会消失 struct
  • 使用 iPhone 将图片发布到 Twitter

    我对在 ios4 上使用 Twitter API 完全陌生 我正在寻找将 uiimage 发布到用户页面的最简单方法 如何 use http dev twitpic com http dev twitpic com 在此处发布您的 http
  • jQuery 中元素的总宽度(包括内边距和边框)

    正如主题所示 如何使用 jQuery 获取元素的总宽度 包括其边框和填充 我已经有了 jQuery 尺寸插件 并且正在运行 width on my 760px wide 10px paddingDIV 回报760 也许我做错了什么 但如果我
  • 有什么方法可以初始化 unique_ptr 向量吗?

    例如 struct A vector
  • React - 作为 npm 包发布的组件之间的通信和路由

    我正在尝试为该项目设置微前端架构 该项目包含多个react应用 以下是项目结构 容器 标头 npm 包 仪表板 npm 包 app1 npm 包 app2 npm 包 app3 npm 包 在这里 容器充当其他应用程序的包装器 仪表板应用程
  • 带 where 子句的 T-SQL Group by

    Masterid CC CLA DES NLCLA NLDES 53006141 CN 0 0 1 1 53006141 US 1 1 1 1 53006141 UK 1 1 0 0 53006142 US 1 1 0 0 53006142
  • 在危险的SetInnerHTML中传递反应组件

    服务器返回类似以下内容 内容 p Hello world smile strong NICE strong p 这是因为我们支持降价 现在我有一个解析器可以解析所有内容 text 变成表情符号 我在用emoji mart对于这个 这就是内容
  • 自动从外部文件替换表

    我正在尝试使用外部 XML 文件替换大型 300 MB XML 文件中的多个表 大约有 30 000 个表 并且有 23 000 个 XML 文件 因为某些表未更改 例如 如果我有