我今天遇到一个我无法解决的问题。
上下文
我有一个带有这种输入的目录:
<catalogue>
<produit>
<nom>mince</nom>
<sku>25</sku>
<criterias>
<criteria>65</criteria>
<criteria>25</criteria>
</criterias>
</produit>
<produit>
<nom>gros</nom>
<sku>56</sku>
<criterias>
<criteria>35</criteria>
<criteria>8</criteria>
</criterias>
</produit>
</catalogue>
我想将其转换为EDN。事实上,我成功获得了样本数据;这是第一步(然后我只进行延迟处理):
(defn catalog-fr-to-edn []
(let [content (slurp "catalog-fr.xml")]
(->> (xml/parse-str content)
(into {}))))
但是,正如你所看到的 - 也许我会错过一些东西 - 但我没有看到从这个库解析XML的其他方法,除了将所有内容作为STR。问题是我有700 MB的数据!
所以我想要更好的东西
1)首先删除“目录”行
<produit>
<nom>mince</nom>
<sku>25</sku>
<criterias>
<criteria>65</criteria>
<criteria>25</criteria>
</criterias>
</produit>
<produit>
<nom>gros</nom>
<sku>56</sku>
<criterias>
<criteria>35</criteria>
<criteria>8</criteria>
</criterias>
</produit>
因此,我实际上有N个“XML”文件,它们对应于N个产品。
2)逐行写记录,如
{:sku 25 ...}
问题
我认为第一步是好的(我没有看到文件的尾部,标题是好的)。他是第一部分的脚本
(defn remove-lines [input nskip]
(let [path (->> (decompose-filepath input)
(last)
(str "qsdqsdqsdqsd."))]
(with-open [rdr (io/reader input)]
(with-open [wrt (io/writer path)]
(loop [n nskip]
(let [line (.readLine rdr)]
(cond (nil? line)
nil
(and (not (nil? line)) (not (empty? (re-find #"<\\catalogue>.*" line))))
nil
:else
(cond (pos? n)
(recur (dec n))
:else
(do (doto wrt (.write line) (.newLine))
(recur n))))))))
(io/delete-file input)
(rename-file path input)))
现在我想做第二步,但我不知道如何做到这一点。我可以为1个产品做这个,但我不知道如何在文件中保存位置。
XML解析是可以的,所以让我说我只想要那样的行作为输出(我删除可见性换行符):
"<produit><nom>mince</nom><sku>25</sku><criterias><criteria>65</criteria><criteria>25</criteria></criterias></produit>"
即。阅读内容直到达到,阅读阅读文章,写下来,然后跳到下一篇文章。
我需要其他Java类吗?如果它更好,我可以使用Java代码。
或者我想错过clojure.data.xml
图书馆的内容?
由于
答案 0 :(得分:0)
它有点幼稚,它是Java代码,但它很容易移植到Clojure。因为我不需要它,所以我没有深入尝试
包文件;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CatalogReader {
public static void processFile (String input, String output) throws FileNotFoundException {
try {
// File input
FileInputStream fstream = new FileInputStream(input);
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader (new InputStreamReader(in));
//File output
File out = new File(output);
FileOutputStream fos = new FileOutputStream(out);
BufferedWriter bw = new BufferedWriter (new OutputStreamWriter(fos));
String line;
String product = "";
Pattern pat = Pattern.compile("</catalogue>");
Matcher mat;
while ((line = br.readLine()) != null) {
mat = pat.matcher(line);
while (!mat.find()) {
product.concat(line);
}
bw.write(product);
bw.newLine()
product = "";
}
br.close();
bw.close();
}
catch (IOException e) { System.err.println("Error: " + e.getMessage());}
}
}