我想在没有一些节点的情况下重新编写一个大的xml。 我正在尝试使用system.xml.xmlreader逐行读取一个XML文件(100个MB,无法将其全部读取到内存中) - 努力寻找一种方法来读取它的一部分,将它们写成一个单独的xDocument然后将该xDocument保存到磁盘。
我一直在想的是:
using (XmlReader reader = XmlReader.Create(_xml_path))
{
using (XmlWriter writer = XmlWriter.Create(@"filteredxml.xml"))
{
reader.MoveToContent();
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
if (reader.Name != "EL_TO_BE_REMOVED")
{
//writer.WriteNode(reader.ReadOuterXml());
}
}
}
}
}
但是reader.ReadOuterXml()只是转到第一个元素并将其所有后代写入文件,而不让我过滤掉我想忽略的元素。
答案 0 :(得分:1)
这听起来像是XSLT的工作。
XSL Transform(RemoveElement.xslt):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="EL_TO_BE_REMOVED" />
</xsl:stylesheet>
执行转换的C#代码:
var transform = new XslCompiledTransform();
transform.Load("xslt/path/RemoveElement.xslt");
transform.Transform("input/xml/path/inputFile.xml", "output/xml/path/outputFile.xml");
答案 1 :(得分:0)
如果存在大文件和内存限制,则应使用SAX而不是DOM进行解析:XMLReader确实是C#等效。
这可能是一个基本方法,其中包含用于输入的XMLReader,用于输出的XMLWriter以及用于删除名为RemoveMe的节点(包含其所有内容)的计数器。
注意内部循环以克隆每个相关元素的属性。
import UIKit
import Firebase
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var dataFeed = [dataS]()
let pagingSpinner = UIActivityIndicatorView(activityIndicatorStyle: .Gray)
var totalNoOfPost : Int!
@IBOutlet weak var customTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
customTableView.delegate = self
customTableView.dataSource = self
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
FIRDatabase.database().reference().child("Posts").observeSingleEventOfType(.Value, withBlock: {(snap) in
if let postDict = snap.value as? [String:AnyObject]{
self.totalNoOfPost = postDict.count
self.loadMore()
}
})
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataFeed.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = customTableView.dequeueReusableCellWithIdentifier("customCell") as! customTableViewCell
if dataFeed.count > 0{
cell.poatLabel.text = dataFeed[indexPath.row].postData
}
return cell
}
func loadMore(){
let initialFeedCount : Int = dataFeed.count
if totalNoOfPost - initialFeedCount - 4 > 0{
FIRDatabase.database().reference().child("Posts").queryOrderedByChild("index").queryStartingAtValue(totalNoOfPost - initialFeedCount - 4).queryEndingAtValue(totalNoOfPost - initialFeedCount).observeEventType(.Value, withBlock: {(recievedSnap) in
if recievedSnap.exists(){
for each in recievedSnap.value as! [String:AnyObject]{
let temp = dataS.init(post: each.1["text"] as! String, ind : each.1["index"] as! Int)
self.dataFeed.insert(temp, atIndex: 5 * Int(self.dataFeed.count/5))
self.dataFeed.sortInPlace({$0.index_Initial > $1.index_Initial})
if self.dataFeed.count == initialFeedCount+5{
self.dataFeed.sortInPlace({$0.index_Initial > $1.index_Initial})
self.customTableView.reloadData()
}
}
}
}, withCancelBlock: {(err) in
print(err.localizedDescription)
})
}else if totalNoOfPost - initialFeedCount - 4 <= 0{
FIRDatabase.database().reference().child("Posts").queryOrderedByChild("index").queryStartingAtValue(0).queryEndingAtValue(totalNoOfPost - initialFeedCount).observeEventType(.Value, withBlock: {(recievedSnap) in
if recievedSnap.exists(){
for each in recievedSnap.value as! [String:AnyObject]{
let temp = dataS.init(post: each.1["text"] as! String, ind : each.1["index"] as! Int)
self.dataFeed.insert(temp, atIndex: 5 * Int(self.dataFeed.count/5))
self.dataFeed.sortInPlace({$0.index_Initial > $1.index_Initial})
if self.dataFeed.count == initialFeedCount+4{
self.dataFeed.sortInPlace({$0.index_Initial > $1.index_Initial})
self.customTableView.reloadData()
self.pagingSpinner.stopAnimating()
}
}
}else{
self.pagingSpinner.stopAnimating()
}
}, withCancelBlock: {(err) in
print(err.localizedDescription)
})
}
}
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if (indexPath.row + 1) == dataFeed.count {
print("Displayed the last row!")
pagingSpinner.startAnimating()
pagingSpinner.hidesWhenStopped = true
pagingSpinner.sizeToFit()
customTableView.tableFooterView = pagingSpinner
loadMore()
}
}
}
struct dataS {
var postData : String!
var index_Initial : Int!
init(post : String!, ind : Int!)
{
self.postData = post
self.index_Initial = ind
}
}