我遇到这样一种情况,我正在生成要提交给网络服务的 XML 文件,有时由于数据量超过 30mb 或 50mb。
我需要使用 c#、.net framework 4.0 来压缩文件,而不是拥有大部分数据的节点之一。我不知道我将如何去做。如果有人可以的话,有没有可能请给我一个如何完成此操作的示例。
xml文件是这样的
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<HeaderTalk xmlns="http://www.w3schools.com/xml">
<EnvelopeVersion>2.0</EnvelopeVersion>
<Header>
<MessageDetails>
<Class>CHAR-CLM</Class>
</MessageDetails>
<SenderDetails>
<IDAuthentication>
<SenderID>aaaaaa</SenderID>
<Authentication>
<Method>MD5</Method>
<Role>principal</Role>
<Value>a3MweCsv60kkAgzEpXeCqQ==</Value>
</Authentication>
</IDAuthentication>
<EmailAddress>Someone@somewhere.com</EmailAddress>
</SenderDetails>
</Header>
<TalkDetails>
<ChannelRouting>
<Channel>
<URI>1953</URI>
<Product>My product</Product>
<Version>2.0</Version>
</Channel>
</ChannelRouting>
</TalkDetails>
<Body>
<envelope xmlns="http://www.w3schools.com/xml/">
<PeriodEnd>2013-08-13</PeriodEnd>
<IRmark Type="generic">zZrxvJ7JmMNaOyrMs9ZOaRuihkg=</IRmark>
<Sender>Individual</Sender>
<Report>
<AuthOfficial>
<OffName>
<Fore>B</Fore>
<Sur>M</Sur>
</OffName>
<Phone>0123412345</Phone>
</AuthOfficial>
<DefaultCurrency>GBP</DefaultCurrency>
<Claim>
<OrgName>B</OrgName>
<ref>AB12345</ref>
<Repayment>
<Account>
<Donor>
<Fore>Barry</Fore>
</Donor>
<Total>7.00</Total>
</Account>
<Account>
<Donor>
<Fore>Anthony</Fore>
</Donor>
<Total>20.00</Total>
</Account>
</Repayment>
</Claim>
</Report>
</envelope>
</Body>
</HeaderTalk>
CLAIM 节点 是我想要压缩的内容,因为它可以是包含在 XML 中的数百万条记录。
我是编码方面的新手,我花了很长时间才生成这个 XML,并且一直在寻找压缩节点的方法,但我就是无法让它工作。 结果需要完全相同,直到 DefaultCurrency 节点。 然后
</AuthOfficial>
<DefaultCurrency>GBP</DefaultCurrency>
<CompressedPart Type="zip">UEsDBBQAAAAIAFt690K1</CompressedPart>
</Report>
</envelope>
</Body>
</HeaderTalk>
或
</AuthOfficial>
<DefaultCurrency>GBP</DefaultCurrency>
<CompressedPart Type="gzip">UEsDBBQAAAAIAFt690K1</CompressedPart>
</Report>
</envelope>
</Body>
</HeaderTalk>
先谢谢大家了。或者,如果有人可以建议我可以在哪里查看并了解我想做什么。
为了创建文件,我简单地遍历数据集并使用 XmlElements 编写节点并将 innertexts 设置为我的值..
我以前写的代码是.. //声明
XmlElement GovtSenderClaim = xmldoc.CreateElement("Claim");
XmlElement GovtSenderOrgname = xmldoc.CreateElement("OrgName");
GovtSenderOrgname.InnerText = Charity_name;
GovtSenderClaim.AppendChild(GovtSenderOrgname);
XmlElement GovtSenderHMRCref = xmldoc.CreateElement("ref");
GovtSenderHMRCref.InnerText = strref ;
GovtSenderClaim.AppendChild(GovtSenderref);
XmlElement GovtSenderRepayments = xmldoc.CreateElement("Repayment");
while (reader.Read())
{
XmlElement GovtSenderAccount = xmldoc.CreateElement("Account");
XmlElement GovtSenderDonor = xmldoc.CreateElement("Donor");
XmlElement GovtSenderfore = xmldoc.CreateElement("Fore");
GovtSenderfore.InnerText = reader["EmployeeName_first_name"].ToString();
GovtSenderDonor.AppendChild(GovtSenderfore);
GovtSenderAccount .AppendChild(GovtSenderDonor);
XmlElement GovtSenderTotal = xmldoc.CreateElement("Total");
GovtSenderTotal.InnerText = reader["Total"].ToString();
GovtSenderAccount .AppendChild(GovtSenderTotal);
GovtSenderRepayments.AppendChild(GovtSenderAccount );
}
GovtSenderClaim.AppendChild(GovtSenderRepayments);
GovtSenderReport.AppendChild(GovtSenderClaim);
以及要关闭的其余节点..
最佳答案
您可以试试这个:它只会压缩您选择的节点。它与您的要求略有不同,因为它将替换元素的内容,而元素及其属性保持原样。
{
// You are using a namespace!
XNamespace ns = "http://www.w3schools.com/xml/";
var xml2 = XDocument.Parse(xml);
// Compress
{
// Will compress all the XElement that are called Claim
// You should probably select the XElement in a better way
var nodes = from p in xml2.Descendants(ns + "Claim") select p;
foreach (XElement el in nodes)
{
CompressElementContent(el);
}
}
// Decompress
{
// Will decompress all the XElement that are called Claim
// You should probably select the XElement in a better way
var nodes = from p in xml2.Descendants(ns + "Claim") select p;
foreach (XElement el in nodes)
{
DecompressElementContent(el);
}
}
}
public static void CompressElementContent(XElement el)
{
string content;
using (var reader = el.CreateReader())
{
reader.MoveToContent();
content = reader.ReadInnerXml();
}
using (var ms = new MemoryStream())
{
using (DeflateStream defl = new DeflateStream(ms, CompressionMode.Compress))
{
// So that the BOM isn't written we use build manually the encoder.
// See for example http://stackoverflow.com/a/2437780/613130
// But note that false is implicit in the parameterless constructor
using (StreamWriter sw = new StreamWriter(defl, new UTF8Encoding()))
{
sw.Write(content);
}
}
string base64 = Convert.ToBase64String(ms.ToArray());
el.ReplaceAll(new XText(base64));
}
}
public static void DecompressElementContent(XElement el)
{
var reader = el.CreateReader();
reader.MoveToContent();
var content = reader.ReadInnerXml();
var bytes = Convert.FromBase64String(content);
using (var ms = new MemoryStream(bytes))
{
using (DeflateStream defl = new DeflateStream(ms, CompressionMode.Decompress))
{
using (StreamReader sr = new StreamReader(defl, Encoding.UTF8))
{
el.ReplaceAll(ParseXmlFragment(sr));
}
}
}
}
public static IEnumerable<XNode> ParseXmlFragment(StreamReader sr)
{
var settings = new XmlReaderSettings
{
ConformanceLevel = ConformanceLevel.Fragment
};
using (var xmlReader = XmlReader.Create(sr, settings))
{
xmlReader.MoveToContent();
while (xmlReader.ReadState != ReadState.EndOfFile)
{
yield return XNode.ReadFrom(xmlReader);
}
}
}
解压比较复杂,因为很难替换Xml的内容。最后,我将内容 XNode 拆分为 ParseXmlFragment 中的 Xnode 和 DecompressElementContent 中的 ReplaceAll >.
作为旁注,您在 XML 中有两个相似但不同的命名空间:http://www.w3schools.com/xml 和 http://www.w3schools。 com/xml/
这个其他变体将完全按照您的要求执行(因此它将创建一个 CompressedPart 节点)减去具有压缩类型的属性。
{
XNamespace ns = "http://www.w3schools.com/xml/";
var xml2 = XDocument.Parse(xml);
// Compress
{
// Here the ToList() is necessary, because we will replace the selected elements
var nodes = (from p in xml2.Descendants(ns + "Claim") select p).ToList();
foreach (XElement el in nodes)
{
CompressElementContent(el);
}
}
// Decompress
{
// Here the ToList() is necessary, because we will replace the selected elements
var nodes = (from p in xml2.Descendants("CompressedPart") select p).ToList();
foreach (XElement el in nodes)
{
DecompressElementContent(el);
}
}
}
public static void CompressElementContent(XElement el)
{
string content = el.ToString();
using (var ms = new MemoryStream())
{
using (DeflateStream defl = new DeflateStream(ms, CompressionMode.Compress))
{
// So that the BOM isn't written we use build manually the encoder.
using (StreamWriter sw = new StreamWriter(defl, new UTF8Encoding()))
{
sw.Write(content);
}
}
string base64 = Convert.ToBase64String(ms.ToArray());
var newEl = new XElement("CompressedPart", new XText(base64));
el.ReplaceWith(newEl);
}
}
public static void DecompressElementContent(XElement el)
{
var reader = el.CreateReader();
reader.MoveToContent();
var content = reader.ReadInnerXml();
var bytes = Convert.FromBase64String(content);
using (var ms = new MemoryStream(bytes))
{
using (DeflateStream defl = new DeflateStream(ms, CompressionMode.Decompress))
{
using (StreamReader sr = new StreamReader(defl, Encoding.UTF8))
{
var newEl = XElement.Parse(sr.ReadToEnd());
el.ReplaceWith(newEl);
}
}
}
}
关于C# - XML - 压缩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18212311/
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
是否有任何可用于Ruby的开源压缩/解压库?有没有人实现过LZW?或者,是否有任何使用压缩组件的开源库可以提取出来独立使用?编辑——感谢您的回答!我应该提到我必须压缩的是只驻留在数据库中的长字符串(我不会压缩文件)。此外,如果可以执行此操作的任何库都具有用于客户端压缩/分解的等效JavaScript实现,那将是理想的,因为这将用于Web应用程序。 最佳答案 您会在rubystdlib下找到所有已交付的ruby库的一个很好的列表.我会使用zlib库,它是开放的,无处不在,您会发现几乎所有语言的库!
我想禁用HTTP参数的自动XML解析。但我发现命令仅适用于Rails2.x,它们都不适用于3.0:config.action_controller.param_parsers.deleteMime::XML(application.rb)ActionController::Base.param_parsers.deleteMime::XMLRails3.0中的等价物是什么? 最佳答案 根据CVE-2013-0156的最新安全公告你可以将它用于Rails3.0。3.1和3.2ActionDispatch::ParamsParser::
我如何做Ruby方法"Flatten"RubyMethod在C#中。此方法将锯齿状数组展平为一维数组。例如:s=[1,2,3]#=>[1,2,3]t=[4,5,6,[7,8]]#=>[4,5,6,[7,8]]a=[s,t,9,10]#=>[[1,2,3],[4,5,6,[7,8]],9,10]a.flatten#=>[1,2,3,4,5,6,7,8,9,10 最佳答案 递归解决方案:IEnumerableFlatten(IEnumerablearray){foreach(variteminarray){if(itemisIEnume
我有一个包含100多个zip文件的目录,我需要读取zip文件中的文件以进行一些数据处理,而无需解压缩存档。是否有一个Ruby库可以在不解压缩文件的情况下读取zip存档中的文件内容?使用rubyzip报错:require'zip'Zip::File.open('my_zip.zip')do|zip_file|#Handleentriesonebyonezip_file.eachdo|entry|#Extracttofile/directory/symlinkputs"Extracting#{entry.name}"entry.extract('here')#Readintomemoryc
我最近从C#转向了Ruby,我发现自己无法制作可折叠的标记代码区域。我只是想到做这种事情应该没问题:classExamplebegin#agroupofmethodsdefmethod1..enddefmethod2..endenddefmethod3..endend...但是这样做真的可以吗?method1和method2最终与method3是同一种东西吗?还是有一些我还没有见过的用于执行此操作的Ruby惯用语? 最佳答案 正如其他人所说,这不会改变方法定义。但是,如果要标记方法组,为什么不使用Ruby语义来标记它们呢?您可以使用