Remove certain recurring elements in xml - java

I have a xml and want to remove certain elements from the xml document. Initially I wanted to remove the control characters coming in these elements or completely remove the data in these elements.
My sample payload is as below. I wanted to remove resume/content and comments.
<Jobs>
<candidates>
<address2/>
<application>
<comments><BR />Test emp1711 Newberg St. #4 Oregon, CA 97229 444-123-9752 testcandidate#gmail.com<BR />authorName: Test 1
comment content: <b>To: test test (test.test#yahoo.com)</b><br /><br />From: abc Recruitment Team (test#abc.com)<br /><br />Subject: Tester at abc<br /><br /><TEXTFORMAT LEADING="2"><P ALIGN="LEFT"><FONT FACE="Verdana" SIZE="12" COLOR="#353A3F" LETTERSPACING="0" KERNING="0">Hello test,</FONT></P></TEXTFORMAT><TEXTFORMAT LEADING="2"><P ALIGN="LEFT"><FONT FACE="Verdana" SIZE="12" COLOR="#353A3F" LETTERSPACING="0" KERNING="0"></FONT></P></TEXTFORMAT><TEXTFORMAT LEADING="2"><P ALIGN="LEFT"><FONT FACE="Verdana" SIZE="12" COLOR="#353A3F" LETTERSPACING="0" KERNING="0">Thank you for your interest in our abc opening. </FONT></P></comments>
<disposition>tesr Skills match</disposition>
<eId>xyz</eId>
<gender>Male</gender>
<lastUpdatedDate>1340687163</lastUpdatedDate>
<race>Undefined</race>
<resume>
<content>Test<BR />Human Resources Manager / Business Partner <BR /> portland, Oregon; 4454; <BR /> Phone 020 444456;Mobile 088768999;E-mail test#yahoo.com <BR /></content>
<format>Text</format>
</resume>
<sentDate>1789993473</sentDate>
<source>Linkedin</source>
<sourceType>Import</sourceType>
<veteranStatus>Undefined</veteranStatus>
<workflowState>Offer Accepted</workflowState>
<city>portland</city>
<companyName/>
<country>US</country>
<eId>xyz</eId>
</application>
</candidates>
<candidates>
<address2/>
<application>
<comments><BR />Test emp2711 Newberg St. #4 Oregon, CA 97229 444-123-9752 testcandidate2#gmail.com<BR />authorName: Test 2
</comments>
<disposition>Skills match</disposition>
<eId>xyz</eId>
<gender>female</gender>
<lastUpdatedDate>1340687163</lastUpdatedDate>
<race>Undefined</race>
<resume>
<content>Test<BR />Program Manager / Business Partner <BR /> portland, Oregon; 4454; <BR /> Phone 020 444456;Mobile 088768999;E-mail test#yahoo.com <BR /></content>
<format>Text</format>
</resume>
<sentDate>178444473</sentDate>
<source>Linkedin</source>
<sourceType>Import</sourceType>
<veteranStatus>Undefined</veteranStatus>
<workflowState>Offer Accepted</workflowState>
<city>portland</city>
<companyName/>
<country>US</country>
<eId>xyzabc</eId>`enter code here`
</application>
</candidates>
</Jobs>

Build the XML into a Document using DocumentBuilderFactory and pass it to a function like below: (nodeName would be "comments" etc.)
removeAllNodes(Document doc, String nodeName){
DocumentTraversal t = (DocumentTraversal) doc;
Node root = doc.getDocumentElement();
NodeIterator iterator =
t.createNodeIterator(root, NodeFilter.SHOW_ELEMENT, null, true);
for (Node n = iterator.nextNode(); n != null; n = iterator.nextNode()) {
Element e = (Element) n;
if (nodeName.equals(e.getTagName()))
root.removeChild(e);
}
}

Related

Finding a substring that is enclosed withing double quotes in java

My code :
String content = '<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 64 (93537) - https://sketch.com -->
<title>Group 36 Copy 4</title>
<desc>Created with Sketch.</desc>
<g id="Portal" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group-36-Copy-4" fill="#FFFFFF">
<path d="M0,7.162 L6,8.877 L6.00036056,9 C6.00036056,10.0543618 6.81623835,10.9181651 7.85109822,10.9945143 L8.00036056,11 C9.10493006,11 10.0003606,10.1045695 10.0003606,9 L10.0003606,9 L10.0003606,8.98076197 L16,7.266 L16.0003606,14 C16.0003606,15.1045695 15.1049301,16 14.0003606,16 L2.00036056,16 C0.895791064,16 0.000360563943,15.1045695 0.000360563943,14 L0,7.162 Z M14.0003606,4 C15.1049301,4 16.0003606,4.8954305 16.0003606,6 L16,6.226 L9.99950581,7.94095939 C9.96827529,6.8636983 9.0851817,6 8.00036056,6 C6.94978154,6 6.08839609,6.81003398 6.00669844,7.83960773 L0,6.122 L0.000360563943,6 C0.000360563943,4.8954305 0.895791064,4 2.00036056,4 L14.0003606,4 Z" id="Combined-Shape"></path>
<rect id="Rectangle" x="7.00036056" y="7" width="2" height="3" rx="1"></rect>
<path d="M10.0003606,0 C11.0547224,0 11.9185257,0.815877791 11.9948748,1.85073766 L12.0003606,2 L12.0003606,4 L10.0003606,4 L10.0003606,2 L6.00036056,2 L6.00036056,4 L4.00036056,4 L4.00036056,2 C4.00036056,0.945638205 4.81623835,0.0818348781 5.85109822,0.00548573643 L6.00036056,0 L10.0003606,0 Z" id="Path-21" fill-rule="nonzero"></path>
</g>
</g>
</svg>'
I have a string named "content" in java which holds any svg file's content that the user uploads. Now my task is to replace the value that is inside this attribute fill="#FFFFFF" with the input that my user has given.
Example : user input : ff0000
so now content string must replace this line <g id="Group-36-Copy-4" fill="#FFFFFF"> as <g id="Group-36-Copy-4" fill="#ff0000">
I am stucked. Please help.
if the fill you mention in the content never change, you can use the replace function.
content = content.replace("#FFFFFF",input)
Reference : https://www.javatpoint.com/java-string-replace
First, your code is not compilable, because you are using single quote which is for character type, you need to use double quotes for your String and escape all internal double quotes:
String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><svg width=\"16px\" height=\"16px\" viewBox=\"0 0 16 16\" version=\"1.1\"xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><!-- Generator: Sketch 64 (93537) - https://sketch.com --><title>Group 36 Copy 4</title><desc>Created with Sketch.</desc><g id=\"Portal\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\"><g id=\"Group-36-Copy-4\" fill=\"#FFFFFF\"><path d=\"M0,7.162 L6,8.877 L6.00036056,9 C6.00036056,10.0543618 6.81623835,10.9181651 7.85109822,10.9945143 L8.00036056,11 C9.10493006,11 10.0003606,10.1045695 10.0003606,9 L10.0003606,9 L10.0003606,8.98076197 L16,7.266 L16.0003606,14 C16.0003606,15.1045695 15.1049301,16 14.0003606,16 L2.00036056,16 C0.895791064,16 0.000360563943,15.1045695 0.000360563943,14 L0,7.162 Z M14.0003606,4 C15.1049301,4 16.0003606,4.8954305 16.0003606,6 L16,6.226 L9.99950581,7.94095939 C9.96827529,6.8636983 9.0851817,6 8.00036056,6 C6.94978154,6 6.08839609,6.81003398 6.00669844,7.83960773 L0,6.122 L0.000360563943,6 C0.000360563943,4.8954305 0.895791064,4 2.00036056,4 L14.0003606,4 Z\" id=\"Combined-Shape\"></path><rect id=\"Rectangle\" x=\"7.00036056\" y=\"7\" width=\"2\" height=\"3\" rx=\"1\"></rect><path d=\"M10.0003606,0 C11.0547224,0 11.9185257,0.815877791 11.9948748,1.85073766 L12.0003606,2 L12.0003606,4 L10.0003606,4 L10.0003606,2 L6.00036056,2 L6.00036056,4 L4.00036056,4 L4.00036056,2 C4.00036056,0.945638205 4.81623835,0.0818348781 5.85109822,0.00548573643 L6.00036056,0 L10.0003606,0 Z\" id=\"Path-21\" fill-rule=\"nonzero\"></path></g></g></svg>";
then you can use String's replace:
content = content.replace("fill=\"#FFFFFF\"", String.format("fill=\"%s\"", replacement));
this, in case you want to replace in the same variable, use a different one otherwise.

Perl - Convert a nested XML format to Java with recursion

I need to convert a nested XML format as below to Java using Perl:
<invoke name="name1" operation="operation1" displayName="Invoke1" id="6">
<input>
<parameter name="Value" variable="Value"/>
<parameter name="ID" variable="ID"/>
</input>
<output>
<parameter name="Return" variable="Return"/>
</output>
</invoke>
<switch name="..." displayName="..." id="13">
<case id="14">
<condition expressionLanguage="..."><![CDATA[(c1)]]></condition>
</case>
<otherwise id="106">
<switch name="..." displayName="..." id="15">
<case id="16">
<condition expressionLanguage="..."><![CDATA[(c2)]]></condition>
<switch name="..." displayName="..." id="19">
<case id="20">
<condition expressionLanguage="..."><![CDATA[(c3) >0)]]></condition>
</case>
<otherwise id="106"> </otherwise>
</switch>
</case>
<otherwise id="107">
<switch name="..." displayName="..." id="33">
<case id="64">
<condition expressionLanguage="..."><![CDATA[(c4)]]></condition>
</case>
<otherwise id="108"> </otherwise>
</switch>
</otherwise>
</switch>
</otherwise>
</switch>
The expected output as the following:
<invoke name="name1" operation="operation1" displayName="Invoke1" id="6">
<input>
<parameter name="Value" variable="Value"/>
<parameter name="ID" variable="ID"/>
</input>
<output>
<parameter name="Return" variable="Return"/>
</output>
</invoke>
if(c1) {
}else{
if(c2) {
if(c3) {
}else{
}
}else{
if(c4) {
}else{
}
}
}
I think that it may be implemented using 4 steps:
Read XML file -> get the first switch1 block -> convert to if--else
Get case1 block and otherwise1 block of switch1 block
Implement recursion from step1 for case1 block and otherwise1 block
Read the rest of XML file and do the same from s1
It's actually difficult for me to do recursion in this case. Can some Perl experts help me here ?
Here's a solution that uses XML::Parser. I've used Style => 'Subs' because the only events I'm interested in are the start and end of case and otherwise elements, and non-blank character data
The array #indent has another element pushed onto it every time we descend into a block, and the last element is popped off when the block ends. The value of the last element in the array is the number of case elements we've seen so far at this level. That allows us to output else if for all occurrences after the first
I've wrapped the whole of the text in parentheses, because your third condition element contains (c3) >0, which doesn't make sense otherwise
I trust that it's clear enough for you to make any adjustments that you may need
use strict;
use warnings 'all';
use XML::Parser;
my $parser = XML::Parser->new(
Style => 'Subs',
Handlers => { Char => \&handle_char },
);
my #indent = (0);
$parser->parse(*DATA);
sub indent {
' ' x $#indent;
}
sub case {
print indent;
print "else " if $indent[-1] > 0;
print "if ( ";
push #indent, 0;
}
sub case_ {
pop #indent;
++$indent[-1];
print indent, "}\n";
}
sub otherwise {
print indent, "else {\n";
push #indent, 0;
}
sub otherwise_ {
pop #indent;
print indent, "}\n";
}
sub handle_char {
my ($expat, $string) = #_;
print $string, " ) {\n" if $string =~ /\S/;
}
__DATA__
<root>
<switch name="..." displayName="..." id="13">
<case id="14">
<condition expressionLanguage="..."><![CDATA[(c1)]]></condition>
</case>
<otherwise id="106">
<switch name="..." displayName="..." id="15">
<case id="16">
<condition expressionLanguage="..."><![CDATA[(c2)]]></condition>
<switch name="..." displayName="..." id="19">
<case id="20">
<condition expressionLanguage="..."><![CDATA[(c3) >0)]]></condition>
</case>
<otherwise id="106">
</otherwise>
</switch>
</case>
<otherwise id="107">
<switch name="..." displayName="..." id="33">
<case id="64">
<condition expressionLanguage="..."><![CDATA[(c4)]]></condition>
</case>
<otherwise id="108">
</otherwise>
</switch>
</otherwise>
</switch>
</otherwise>
</switch>
</root>
output
if ( (c1) ) {
}
else {
if ( (c2) ) {
if ( (c3) >0) ) {
}
else {
}
}
else {
if ( (c4) ) {
}
else {
}
}
}

XPAGES : take the answer of user by the dropdownbutton

I try to recover the answer of the user but i can't.
I have a dropdownbutton, I recover the list and the value by default by a java class.
It's ok about this.
But when I try to push another text of the list : nothing append...
<xe:dropDownButton id="dropdownEtatDoc">
<xe:this.treeNodes>
<xe:basicContainerNode>
<!-- Affiche l'état du document par défaut-->
<xe:this.label id="labelEtatDoc">
<![CDATA[#{javascript:
etatDoc.nomEtatDoc;
}]]>
</xe:this.label>
<!-- affiche la liste des états du document-->
<xe:repeatTreeNode var="index" value="#{etatDoc.listEtatDoc}">
<xe:this.children>
<xe:basicLeafNode label="#{index}" submitValue="#{index}" />
</xe:this.children>
</xe:repeatTreeNode>
</xe:basicContainerNode>
</xe:this.treeNodes>
<!-- actualise la chaine sélectionnée-->
<xp:eventHandler event="onItemClick" submit="true"
refreshMode="complete">
<xp:this.action>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:
var montest = getComponent("dropdownEtatDoc").submittedValue();
etatDoc.nomEtatDoc = montest;
}]]></xp:this.script>
</xp:executeScript>
</xp:this.action>
</xp:eventHandler>
</xe:dropDownButton>
An idea ? Thanks !
I use a combobox and it's ok, I don't know why...
My code for anyone has the same problem :
<xp:this.beforePageLoad>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:
viewScope.etat = etatDoc.listEtatDoc;
viewScope.grdFam = chapitre.listChapitre1;
}]]></xp:this.script>
</xp:executeScript>
</xp:this.beforePageLoad>
<xp:div>
<!--**************** DEBUT CBXETATDOC *************************************************************-->
<xp:label value="Etat : " id="label1"></xp:label>
<xp:comboBox id="cbxEtat">
<xp:selectItem itemLabel="Tout" itemValue="" />
<xp:selectItems value="#{viewScope.etat}" />
<xp:eventHandler event="onchange" submit="true" refreshMode="complete" immediate="true">
<xp:this.action>
<xp:executeScript>
<xp:this.script>
<![CDATA[#{javascript:
var etat = getComponent("cbxEtat").submittedValue;
}]]>
</xp:this.script>
</xp:executeScript>
</xp:this.action>
</xp:eventHandler>
</xp:comboBox>
Assuming "etatDoc" is a NotesXspDocument and not a bean.
1) If you are having trouble getting the submitted value, get it via the context:
var submitted = context.getSubmittedValue();
print("submitted: " + submitted); //check if it is there, delete afterward
switch(submitted){
case("btn1")
//doSomething(submitted);
break;
}
Since you are using the repeater node, it would not be practical to use the switch for all of it, but you could make a default where you do what ever you need to with the index value.
2) then I do not think you are setting the value properly. Try:
var montest = submitted;
etatDoc.replaceItemValue("nomEtatDoc", etatDoc.getItemValue("nomEtatDoc").add(montest))
//gets the current list (java.util.Vector) from the document
//add a value to the list
//replace the value with the new list
I am assuming that you are not using a self-made-bean for this.

java.lang.String cannot be cast to java.util.Map$Entry and pagination missing required attribute

I have this list method in user controller
def listUser(Integer max) {
params.max = Math.min(max ?: 10, 100)
[userInstanceList: User.list(params), userInstanceTotal: User.count()]
}
and under myView.gsp
<g:sortableColumn params="[controller='user']" property="username" title="${message(code: 'user.username.label', default: 'Username')}" />
but it gives me an error java.lang.String cannot be cast to java.util.Map$Entry
also the paginate
<div class="pagination">
<g:paginate controller="user" action="listUser" total="${userInstanceTotal}" />
</div>
gives a Tag [paginate] is missing required attribute [total] error
though when its under listUser.gsp both errors are gone
<g:sortableColumn params="[controller='user']" ...>
That equals sign should be a colon
<g:sortableColumn params="[controller:'user']" ...>

Flex/Flash 4 datagrid displays raw xml

Problem: Flex/Flash4 client (built with FlashBuilder4) displays the xml sent from the server exactly as is - the datagrid keeps the format of the xml. I need the datagrid to parse the input and place the data in the correct rows and columns of the datagrid.
flow: click on a date in the tree and it makes a server request for batch information in xml form. Using a CallResponder I then update the datagrid's dataProvider.
[code]
<fx:Script>
<![CDATA[
import mx.controls.Alert;
[Bindable]public var selectedTreeNode:XML;
public function taskTreeChanged(event:Event):void {
selectedTreeNode=Tree(event.target).selectedItem as XML;
var searchHubId:String = selectedTreeNode.#hub;
var searchDate:String = selectedTreeNode.#lbl;
if((searchHubId == "") || (searchDate == "")){
return;
}
findShipmentBatches(searchDate,searchHubId);
}
protected function findShipmentBatches(searchDate:String, searchHubId:String):void{
findShipmentBatchesResult.token = actWs.findShipmentBatches(searchDate, searchHubId);
}
protected function updateBatchDataGridDP():void{
task_list_dg.dataProvider = findShipmentBatchesResult.lastResult;
}
]]>
</fx:Script>
<fx:Declarations>
<actws:ActWs id="actWs" fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)" showBusyCursor="true"/>
<s:CallResponder id="findShipmentBatchesResult" result="updateBatchDataGridDP()"/>
</fx:Declarations>
<mx:AdvancedDataGrid id="task_list_dg" width="100%" height="95%" paddingLeft="0" paddingTop="0" paddingBottom="0">
<mx:columns>
<mx:AdvancedDataGridColumn headerText="Receiving date" dataField="rd"/>
<mx:AdvancedDataGridColumn headerText="Msg type" dataField="mt"/>
<mx:AdvancedDataGridColumn headerText="SSD" dataField="ssd"/>
<mx:AdvancedDataGridColumn headerText="Shipping site" dataField="sss"/>
<mx:AdvancedDataGridColumn headerText="File name" dataField="fn"/>
<mx:AdvancedDataGridColumn headerText="Batch number" dataField="bn"/>
</mx:columns>
</mx:AdvancedDataGrid>
//xml example from server
<batches>
<batch>
<rd>2010-04-23 16:31:00.0</rd>
<mt>SC1REVISION01</mt>
<ssd>2010-02-18 00:00:00.0</ssd>
<sss>100000009</sss>
<fn>Revision 1-DF-Ocean-SC1SUM-Quanta-PACT-EMEA-Scheduled Ship Date 20100218.csv</fn>
<bn>10041</bn>
</batch>
<batches>
[/code]
and the xml is pretty much displayed exactly as is shown in the example above in the datagrid columns...
I would appreciate your assistance.
I tried a simplified version of your sample using a simple xml literal, and it works fine for me..
here's what I've got
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
protected function onCreationCompleteHandler(event:FlexEvent):void
{
task_list_dg.dataProvider = data..batch;
}
private var data:XML = //xml example from server
<batches>
<batch>
<rd>2010-04-23 16:31:00.0</rd>
<mt>SC1REVISION01</mt>
<ssd>2010-02-18 00:00:00.0</ssd>
<sss>100000009</sss>
<fn>Revision 1-DF-Ocean-SC1SUM-Quanta-PACT-EMEA-Scheduled Ship Date 20100218.csv</fn>
<bn>10041</bn>
</batch>
</batches>;
]]>
</fx:Script>
<mx:AdvancedDataGrid id="task_list_dg" width="100%" height="95%" paddingLeft="0" paddingTop="0" paddingBottom="0">
<mx:columns>
<mx:AdvancedDataGridColumn headerText="Receiving date" dataField="rd"/>
<mx:AdvancedDataGridColumn headerText="Msg type" dataField="mt"/>
<mx:AdvancedDataGridColumn headerText="SSD" dataField="ssd"/>
<mx:AdvancedDataGridColumn headerText="Shipping site" dataField="sss"/>
<mx:AdvancedDataGridColumn headerText="File name" dataField="fn"/>
<mx:AdvancedDataGridColumn headerText="Batch number" dataField="bn"/>
</mx:columns>
</mx:AdvancedDataGrid>
Are you sure your data is arriving in the format you're suggesting?
(check the Data/Services tab in FB)
What do you mean by "displays the xml sent from the server exactly as is - the datagrid keeps the format of the xml" ? does it dump xml content in the grid cells?
Edit: Have you tried doing this?
protected function updateBatchDataGridDP():void{
task_list_dg.dataProvider = findShipmentBatchesResult.lastResult..batch;
}
had to resort to this monstrosity ----> is there a better way???
protected function updateBatchDataGridDP():void{
var batches:XML = new XML(findShipmentBatchesResult.lastResult);
task_list_dg.dataProvider = batches.batch;
var task_list_col1:AdvancedDataGridColumn = new AdvancedDataGridColumn();
task_list_col1.dataField = "#rd";
task_list_col1.headerText = "Receiving date";
var task_list_col2:AdvancedDataGridColumn = new AdvancedDataGridColumn();
task_list_col2.dataField = "#mt";
task_list_col2.headerText = "Msg type";
var task_list_col3:AdvancedDataGridColumn = new AdvancedDataGridColumn();
task_list_col3.dataField = "#ssd";
task_list_col3.headerText = "SSD";
var task_list_col4:AdvancedDataGridColumn = new AdvancedDataGridColumn();
task_list_col4.dataField = "#sss";
task_list_col4.headerText = "Shipping site";
task_list_status.text = batches.batch.#sss;
var task_list_col5:AdvancedDataGridColumn = new AdvancedDataGridColumn();
task_list_col5.dataField = "#fn";
task_list_col5.headerText = "File name";
var task_list_col6:AdvancedDataGridColumn = new AdvancedDataGridColumn();
task_list_col6.dataField = "#bn";
task_list_col6.headerText = "Batch number";
var myColumns:Array = new Array();
myColumns.push(task_list_col1);
myColumns.push(task_list_col2);
myColumns.push(task_list_col3);
myColumns.push(task_list_col4);
myColumns.push(task_list_col5);
myColumns.push(task_list_col6);
task_list_dg.columns = myColumns;
}
with this xml structure:
<batches>
<batch rd="2010-04-23 16:31:00.0" mt="SC1REVISION01" ssd="2010-02-18 00:00:00.0" sss="Quanta" fn="Revision 1-DF-Ocean-SC1SUM-Quanta-PACT-EMEA-Scheduled Ship Date 20100218.csv" bn="SHA201004230033" />
<batch rd="2010-04-23 16:32:14.0" mt="SC1" ssd="2010-02-11 00:00:00.0" sss="Quanta" fn="DF-Ocean-SC1SUM-Quanta-PACT-EMEA-Scheduled Ship Date 20100211.csv" bn="SHA201004230043" />
<batch rd="2010-04-23 16:35:51.0" mt="PRESHIP" ssd="2010-02-15 00:00:00.0" sss="Quanta" fn="DF-Ocean-PRESHIPSUM-Quanta-PACT-EMEA-Scheduled Ship Date 20100215.csv" bn="SHA201004230045" />
</batches>

Categories