Append bytes to a content of nt:unstructured type of node in jcr - jackrabbit

I want to append some bytes in a already saved file in JCR .How can we do this ?
The file is stored in a nt:unstructured node in the JCR repo. Any suggestions ?

Because of the Binary values are streamed, I don't think you have a choice other than to create a new Binary using the stream of the original plus the extra bytes you want to append. In other words, I know of no utility of built-in functionality, so you have to write this minimal code yourself.

Related

Jackrabbit Oak Binary property in Solr index has not correct value

I use remote solr index. I have one node type that has a binary property. When I add a node with this type and attach some non empty text file, oak add a document in solr but the value of binary field is some new line character.
I trace it and find that the binary value that extract in SolrIndexEditor class line 235 return a LinkedList with one entry that just contain "\n\n\n\n\n". Is there any config that I missed or there is a bug here?
I missed the tika parser in my dependencies. So by adding it the problem solved. I fine the answer here

Appending a big number of nodes to an xml tree

I'm using libxml via C, to work with xml file creation and parsing. Until recently everything worked smoothly, but a case emerged where a single tree has a subnode, lets call it S, with approximately 200,000 children. This case works surprisingly slow and I suspect the function :
xmlNewChild(/**/);
which I'm using to build the tree, has to iterate over every child of S to add one more child. Since a function that also accepts a hint (a pointer to the last added function) doesn't seem to exist, is there a better way to build the tree (maybe a batch build method) ? In case such numbers are insignificant and I should search for deficiencies elsewhere, please let me know.
Yeah, rather than keeping the entire XML in memory with xmlTree, you may want to use a combination of libxml's xmlReader and xmlWriter APIs. They're both streaming, so it won't have to keep the entire document in memory and won't have any scaling problems based on the number of elements.
Examples of both xmlReader and xmlWriter can be found here:
http://www.xmlsoft.org/examples/index.html

Read & Process in memory XML data in a streaming manner in C

Original question below, update regarding solution, if someone has a similar problem:
For a fast regex I found http://re2c.org/ ; for xml parsing http://expat.sourceforge.net/
Is there an xml library I can use to parse xml from memory (and not from file) in a streaming manner in c?
Currently I have:
libxml2 ; XMLReader seems to only be possible to use with a filehandle and not in-memory
rapidxml is c++ and does not seem to expose a c interface
Requirements:
I need to process the individual xml nodes without having the whole xml (400GB uncompressed, and "only" 29GB as original .bz2 file) in memory ( bzip'd file gets read in and decompressed piecewise, and I would pass those uncompressed pieces to be consumed by the xml parser )
It does not need to very fast, but I would prefer an efficient solution
I (most probably) don't need the path of an extracted node, so it would be fine to just discard them as soon as they have been processed by my callback (if I would need the path contrary to what I think right now, I could then still track it myself)
This is part of me trying to solve my own problem posted here (and no, it's not the same question): How to efficiently parse large bz2 xml file in C
Ideally I'd like to be able to feed the library a certain amount of bytes at a time and have a function called whenever a node is completed.
Thank you very much
Here's some pseudo c code (way shorter than actual c code) for a better understanding
// extracted data gets put here
strm.next_out = buffer_ptr;
while( bytes_processed_total < filesize ) {
// extracts up to amount of data set in strm.avail_in
BZ2_bzDecompress( strm );
bytes_processed = strm.next_out - buffer_ptr;
bytes_processed_total += bytes_processed;
// here I would like to pass bytes_processed of buffer_ptr to xmlreader
}
About the data I want to parse: http://wiki.openstreetmap.org/wiki/OSM_XML
At the moment I only need certain <node ...> nodes from this, which have subnode <tag k="place" v="country|county|city|town|village"> (the '|' means at least one of those in this context, in the file it's of course only "country" etc without the '|')
xmlReaderForMemory from libxml2 seems a good one to me (but haven't used it so, I may be wrong)
the char * buffer needs to point to a valid XML document (that can be a part of your entire XML file). This can be extracted reading in chuncks your file but obtaining a valid XML fragment.
What's the structure of your XML file ? A root containing subsequent similar nodes or a fully fledged tree ?
If I had an XML like this:
<root>
<node>...</node>
<node>...</node>
<node>...</node>
</root>
I'd read starting from the opening <node> till the closing </node> and then parse it with the xmlReaderForMemory function, do what I need to do, then go on with the next <node> node.
Ofc if your <node> content is too complex/long, you may have to go deep some levels:
<node>
<subnode>....</subnode>
<subnode>....</subnode>
<subnode>....</subnode>
<subnode>....</subnode>
</node>
And read from the file until you have the entire <subnode> node (but keeping track that you're in a <node>.
I know it's ugly, but is a viable way. Or you can try to use a sax parser (dunno if some C implementation exists).
Sax parsing fires events on each node start and node end, so you can do nothing untill you find your nodes and process just them.
Another viable way can be using some external tools to filter the whole XML (XQuery or XPath processors) in order to extract just your interesting nodes from the whole file, obtain a smaller doc and then work on it.
EDIT: Zorba was a good XQuery framework, with command line preprocessor, may be a good place to look at
EDIT2: well since you have this dimensions, one alternative solution can be manage the file as a text file, so read and uncompress in chunks and then matching something like:
<yourNode>.*</yourNode>
with regexp.
If you're on a Linux/Unix you should have POSIX regexp library. Check
this question on S.O. for further insights.

JCR create single file, link from different nodes

I am trying to create a single file node for an image with name (say A.gif). Now, I want to re-use the file across multiple nodes. Is there a way to do this?
As a workaround, I am re-creating file nodes for different paths in my repository, but this results in duplication of files.
If you're using jackrabbit, copying a file node (or rather copying a binary property) is cheap if the DataStore is active.
That component makes sure "large" binary properties (with a configurable size threshold IIRC) are stored once only, based on a digest of their content.
So you can in this case copy the same file node many times without having to worry about disk space.
I'm not sure I understand your problem. However, what I would do is store the file in a single location and then reference it using a path property from multiple locations.
Assume that you have an the following node structure
-content
- articles
- article1
- article2
- images
- image1
You can set on each of the articles a property named imagePath which points to the path of the image to display, in this case /content/images/image1.
The nt:linkedFile type was made for just this kind of use.
And just for completeness, don't forget references.
Node imageNode = rootNode.addNode("imageNode");
imageNode.addMixin(JcrConstants.MIX_REFERENCEABLE);
Node node1 = rootNode.addNode("1");
node1.setProperty("image", imageNode);
Node node2 = rootNode.addNode("2");
node2.setProperty("image", imageNode);
session.save();
PropertyIterator references = imageNode.getReferences();
while (references.hasNext()) {
Property reference = references.nextProperty();
System.out.println(reference.getPath());
}

libxml xmlNodePtr to raw xml string?

Given a valid, arbitrary xmlNodePtr, I would like the string representation of that node, including the tag, attributes, and children in the same form (recursive).
FWIW, my scenario is I am using PerformXPathQuery to get a block of data from within an existing document. I need to get the results of the query, which has nested XML elements in it, as the raw string, so I can insert it into a text field.
These seems like a simple task, however I cannot find an easy way. Writing an xmlDocPtr to file must do this, however, I cannot see a handy method that will do the same thing to an arbitrary node in the tree, and return it in memory.
I hope I am just going blind from the brown-on-brown documentation color scheme at xmlsoft.org
Is xmlNodeDump (or xmlNodeDumpOutput) what you are looking for?
My code I used to dump a node to a string. It's objectiv-c so just change your output as needed.
xmlBufferPtr buffer = xmlBufferCreate();
int size = xmlNodeDump(buffer, myXMLDoc, myXMLNode, 0, 1);
NSLog(#"%d", size);
NSLog(#"%s", buffer->content);
Don't forget to free your buffer again.
One way you could do it definitely is to create a new document, then use xmlDocCopyNode to copy the node into it and serialize it.

Resources