XML文件没有使用jdom进行更新(XML file is not updating using the jdom)
以下是我的java代码,用于读取xml文件并更新其中的一些值。
public static void writeLexicon(String word, String tag) { int newFreq=0; int tagAvailability = 0; int wordAvaialbility = 0; try { if (new File("./src/Lexicon.xml").exists()) { Document readDoc = getXMLFile(); Element root = readDoc.getRootElement(); for (Element curElem : root.getChildren("lexiconElement")) { if (word.equals(curElem.getChildText("word"))) { // word avaialble List<Element> subEle = curElem.getChildren(); for (int i = 1; i < subEle.size(); i++) { if (tag.equals(subEle.get(i).getChildText("tag"))) { int curFreq = Integer.parseInt(subEle.get(i).getChildTextTrim("frequancy")); newFreq = curFreq + 1; subEle.get(i).getChild("frequancy").setText(String.valueOf(newFreq)); tagAvailability = 1; //break; } } if (tagAvailability == 0) { Element newTag = new Element("tag").setText(tag); Element newFrequancy = new Element("frequancy").setText("1"); newTag.addContent(newFrequancy); curElem.addContent(newTag); } wordAvaialbility = 1; } } if (wordAvaialbility == 0) { Element lexiconElement = new Element("lexiconElement"); Element newWord = new Element("word").setText(word); Element newTag = new Element("tag").setText(tag); Element newFrequancy = new Element("frequancy").setText("1"); newTag.addContent(newFrequancy); lexiconElement.addContent(newWord); lexiconElement.addContent(newTag); root.addContent(lexiconElement); XMLOutputter xmlOutput = new XMLOutputter(Format.getPrettyFormat()); xmlOutput.output(readDoc, new FileOutputStream(new File("./src/Lexicon.xml"))); } } else { Document doc = new Document(); // create a JDOM document String freq = "1"; Element theRoot = new Element("Lexicon"); // Creates a element named Lexicon and makes it the root doc.setRootElement(theRoot); Element lexiconElement = new Element("lexiconElement"); Element Word = new Element("word"); Element Tag = new Element("tag"); Element frequency = new Element("frequency"); Word.addContent(new Text(word)); Tag.addContent(new Text(tag)); frequency.addContent(new Text(freq)); Tag.addContent(frequency); lexiconElement.addContent(Word); lexiconElement.addContent(Tag); theRoot.addContent(lexiconElement); XMLOutputter xmlOutput = new XMLOutputter(Format.getPrettyFormat()); xmlOutput.output(doc, new FileOutputStream(new File("./src/Lexicon.xml"))); } } catch (Exception e) { System.out.println(e); } }
我需要获取frequancy标记中的值并将值递增1并添加到相同的xml文件中。 但它没有使用上面的代码。
以下是我的xml文件中的几个元素。
<lexiconElement> <word>හයිටිය</word> <tag> NNPI <frequency>1</frequency> </tag> </lexiconElement> <lexiconElement> <word>-2</word> <tag> QFNUM <frequancy>1</frequancy> </tag> </lexiconElement> <lexiconElement> <word>තමා</word> <tag> PRP <frequancy>1</frequancy> </tag> </lexiconElement>
following is my java code for reading a xml file and updating some values in it.
public static void writeLexicon(String word, String tag) { int newFreq=0; int tagAvailability = 0; int wordAvaialbility = 0; try { if (new File("./src/Lexicon.xml").exists()) { Document readDoc = getXMLFile(); Element root = readDoc.getRootElement(); for (Element curElem : root.getChildren("lexiconElement")) { if (word.equals(curElem.getChildText("word"))) { // word avaialble List<Element> subEle = curElem.getChildren(); for (int i = 1; i < subEle.size(); i++) { if (tag.equals(subEle.get(i).getChildText("tag"))) { int curFreq = Integer.parseInt(subEle.get(i).getChildTextTrim("frequancy")); newFreq = curFreq + 1; subEle.get(i).getChild("frequancy").setText(String.valueOf(newFreq)); tagAvailability = 1; //break; } } if (tagAvailability == 0) { Element newTag = new Element("tag").setText(tag); Element newFrequancy = new Element("frequancy").setText("1"); newTag.addContent(newFrequancy); curElem.addContent(newTag); } wordAvaialbility = 1; } } if (wordAvaialbility == 0) { Element lexiconElement = new Element("lexiconElement"); Element newWord = new Element("word").setText(word); Element newTag = new Element("tag").setText(tag); Element newFrequancy = new Element("frequancy").setText("1"); newTag.addContent(newFrequancy); lexiconElement.addContent(newWord); lexiconElement.addContent(newTag); root.addContent(lexiconElement); XMLOutputter xmlOutput = new XMLOutputter(Format.getPrettyFormat()); xmlOutput.output(readDoc, new FileOutputStream(new File("./src/Lexicon.xml"))); } } else { Document doc = new Document(); // create a JDOM document String freq = "1"; Element theRoot = new Element("Lexicon"); // Creates a element named Lexicon and makes it the root doc.setRootElement(theRoot); Element lexiconElement = new Element("lexiconElement"); Element Word = new Element("word"); Element Tag = new Element("tag"); Element frequency = new Element("frequency"); Word.addContent(new Text(word)); Tag.addContent(new Text(tag)); frequency.addContent(new Text(freq)); Tag.addContent(frequency); lexiconElement.addContent(Word); lexiconElement.addContent(Tag); theRoot.addContent(lexiconElement); XMLOutputter xmlOutput = new XMLOutputter(Format.getPrettyFormat()); xmlOutput.output(doc, new FileOutputStream(new File("./src/Lexicon.xml"))); } } catch (Exception e) { System.out.println(e); } }
i need to get the value in frequancy tag and increment the value by one and add to same xml file. but it didnt work with the above code.
following are few elements avaialble in my xml file.
<lexiconElement> <word>හයිටිය</word> <tag> NNPI <frequency>1</frequency> </tag> </lexiconElement> <lexiconElement> <word>-2</word> <tag> QFNUM <frequancy>1</frequancy> </tag> </lexiconElement> <lexiconElement> <word>තමා</word> <tag> PRP <frequancy>1</frequancy> </tag> </lexiconElement>
原文:https://stackoverflow.com/questions/26108513
最满意答案
这里有很多方法,但是如果不了解你打算如何使用
istream
,就很难给出好的建议。关于这段代码的一件事是你绝对肯定地知道在
istream
的末尾会有一个换行符。 没有可以采用的代码路径不会导致(除了I / O错误,您将提前捕获)。因此,编写希望
\n
存在并忽略它的代码非常简单。显然,如果可能,您希望避免使用缓冲区副本。
但是,如果要将整个streambuf复制到字符串中,可以尝试这样做:
auto buf = buffer.data(); /* where buffer is your asio::streambuf */ auto s = std::string(boost::asio::buffer_cast<const char*>(buf), boost::asio::buffer_size(buf) - 1); /* remove the newline */
当然,如果你想要解析istream中的字符串,数字等,那么最后有一个换行的事实并不重要 - 它只是空格,默认情况下会被忽略。
这个迷你程序演示了这个:
#include <boost/asio.hpp> #include <sstream> #include <iomanip> #include <iostream> int main() { std::ostringstream oss; oss << 10 << std::quoted("Hello\" World") << '\n'; auto payload = oss.str(); boost::asio::streambuf sb; std::ostream otmp(&sb); otmp.write(payload.data(), payload.size()); // streambuf now contains string with newline std::string s; int i; std::istream itmp(&sb); itmp >> i >> std::quoted(s); std::cout << i << std::endl; // expect 10 std::cout << s << std::endl; // expect Hello" World }
There are a number of approaches here, but it's difficult to give good advice without knowing something about how you intend to use the
istream
.One thing about this code is that you know with absolute certainty that there will be a newline at the end of the
istream
. There is no code path that can be taken that will not result in that (other than an I/O error, which you will catch early).As a result it's straightforward to write code that expects the
\n
to be there and ignore it.Obviously you want to avoid buffer copies if possible.
However, if you want to copy the entire streambuf into a string, you might try this:
auto buf = buffer.data(); /* where buffer is your asio::streambuf */ auto s = std::string(boost::asio::buffer_cast<const char*>(buf), boost::asio::buffer_size(buf) - 1); /* remove the newline */
Of course if you're looking to parse strings, numbers etc out of the istream then the fact that there is a newline on the end won't matter - it's just whitespace which is ignored by default.
This mini program demonstrates this:
#include <boost/asio.hpp> #include <sstream> #include <iomanip> #include <iostream> int main() { std::ostringstream oss; oss << 10 << std::quoted("Hello\" World") << '\n'; auto payload = oss.str(); boost::asio::streambuf sb; std::ostream otmp(&sb); otmp.write(payload.data(), payload.size()); // streambuf now contains string with newline std::string s; int i; std::istream itmp(&sb); itmp >> i >> std::quoted(s); std::cout << i << std::endl; // expect 10 std::cout << s << std::endl; // expect Hello" World }
相关问答
更多-
提升ASIO streambuf(Boost ASIO streambuf)[2022-11-13]
boost::asio::streambuf的命名与C ++标准中定义的命名类似,并且在标准模板库中的各个类中使用,其中数据被写入输出流并且数据从输入流读取。 例如,可以使用std::cout.put()写入输出流,使用std::cin.get()从输入流读取数据。 手动控制streambuf输入和输出序列时,数据的一般生命周期如下: 缓冲区会为输出序列分配prepare() 。 数据写入输出序列的缓冲区后,数据将被commit() 。 此提交的数据将从输出序列中删除,并附加到可从中读取的输入序列。 数据从 ... -
asio :: streambuf to std :: istream丢弃新行(asio::streambuf to std::istream discarding new line)[2024-01-28]
这里有很多方法,但是如果不了解你打算如何使用istream ,就很难给出好的建议。 关于这段代码的一件事是你绝对肯定地知道在istream的末尾会有一个换行符。 没有可以采用的代码路径不会导致(除了I / O错误,您将提前捕获)。 因此,编写希望\n存在并忽略它的代码非常简单。 显然,如果可能,您希望避免使用缓冲区副本。 但是,如果要将整个streambuf复制到字符串中,可以尝试这样做: auto buf = buffer.data(); /* where buffer is your asio::str ... -
Boost有buffers_begin()和buffers_end() ,你可以在streambuf的data() : 住在科利鲁 #include
#include namespace a = boost::asio; namespace qi = boost::spirit::qi; #include int main() { a::streambuf input; ... -
不,幸运的是,绑定并不关心recv_data的内部可能会被重新分配,而是绑定到recv_data对象本身。 这是我写的下载器的一个工作示例,您可以看到我不会在读取之间重新分配缓冲区。 以同样的方式,您可以安全地共享对向量的引用,而不关心是否重新分配向量的内部(除非您开始直接指向向量元素的内存地址,或者在它们变为无效后使用迭代器。)向量仍然有效,并以同样的方式,streambuf的句柄仍然对istream有效,它工作得很好)。 download.h #ifndef _MV_DOWNLOAD_H_ #defin ...
-
缓冲区分配后,您可以使用memcpy填充它: unsigned char* output = (unsigned char*)malloc(buf.size()); memcpy(output, boost::asio::buffer_cast
(buf.data()), buf.size()); After buffer allocation, you can fill it using memcpy : unsigned char* output = (unsigned cha ... -
可以使用boost::asio::buffer_copy()来复制Asio缓冲区的内容。 例如,如果希望将一个streambuf的内容复制到另一个streambuf ,这可能很方便。 boost::asio::streambuf source, target; ... std::size_t bytes_copied = buffer_copy( target.prepare(source.size()), // target's output sequence source.data()); ...
-
您可以轻松发送任何标准流,因此您也可以使用stringstream 。 您可以将二进制数据写入字符串流(它实际上只是一个字节数组)。 一些样本: boost::asio::streambuf request; std::ostream request_stream(&request); request_stream.write(&binarydata_buf, sizeof(binarydata_buf)); // or use stream operators: request_stream << "xx ...
-
我重写了你的例子,它对我来说很好。 请注意,我没有用于阅读响应的快捷方式。 我正在一次性阅读状态行和标题而不是单独阅读(纯粹是出于懒惰) #include
#include #include #include int main(int argc, const char * argv[]) { static asio::io_service ios; asio::ip::tcp::endpoint ... -
如何从boost :: asio :: streambuf获取二进制数据(How to get binary data from boost::asio::streambuf)[2023-04-10]
你可以尝试一下buffer_cast 。 这是一个例子: boost::asio::streambuf buf; size_t bytes = read( *socket_, buf, boost::asio::transfer_at_least(694784) ); buf.commit( bytes ); std::ofstream outfile( "test.exe" ); outfile << boost::asio::buffer_cast( buf.data() ) ... -
不确定你的代码。 这对我有用: boost::asio::streambuf request; std::ostream request_stream(&request); request_stream << "GET " << queryArgs << " HTTP/1.0\r\n"; request_stream << "Host: " << serverIp /* "192.168.0.70" */ << "\r\n"; request_stream << " ...