I have an XML that has a tag value like the following:
<ProjectNote>
<Note><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE></TITLE>
<META http-equiv=Content-Type content="text/html; charset=unicode">
<META content="MSHTML 6.00.3790.4944" name=GENERATOR></HEAD>
<BODY bgColor=#ffffff>
<P>Key Deliverables</P>
<UL>
<LI>schedule development
<LI>scope development (SOW)
<LI>business case (depending on project)
<LI>contracts (who will be used)
<LI>overall budget
<LI>Assign Key Stakeholders
<LI>Sitewalks and PreCon Meetings
<LI>Need Clearance?</LI></UL>
<P> </P></BODY></HTML>
</Note>
<ProjectNote>
I am reading this file with groovy script and making some changes to it and writing it back to the file. However, the " is getting converted to " while parsing the file with XmlSluper. I don't want to change any other section of the file other than adding a new nodeto it. How can I keep the file as it is?
I am using following code:
package test
import groovy.xml.*
/**
* A Simple Example that searches information from XML parsed by XmlSlurper.
*/
class Test {
static srcXMLPath = "C:/SRC_Project/628548_C453_Original.xml"
static updXMLPath = "C:/SRC_Project/628548_C453_Updated.xml"
static def writer
static main(args) {
File srcFile = new File(srcXMLPath)
def baseXMLStr = new XmlSlurper(false,false).parse(srcFile)
def newXMLStr = new groovy.xml.StreamingMarkupBuilder().bind {
List_Wrapper {
mkp.yield baseXMLStr
}
}
writer = new FileWriter(updXMLPath)
groovy.xml.XmlUtil.serialize( newXMLStr,writer )
writer.close()
}
}
However the updated file gets changed to this which is not my intention:
<ProjectNote>
<Note><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE></TITLE>
<META http-equiv=Content-Type content="text/html; charset=unicode">
<META content="MSHTML 6.00.3790.4944" name=GENERATOR></HEAD>
<BODY bgColor=#ffffff>
<P>Key Deliverables</P>
<UL>
<LI>As Builts (if needed)
<UL>
<LI>Mapping & Design Drawings</LI></UL>
<LI>Engineer needs final approval
<P> </P></BODY></HTML>
</Note>
<ProjectNote>
Could someone let me know how to avoid it. it is clearly not changing other escape characters
You may fix it after building markup:
new File(updXMLPath) << XmlUtil.serialize(newXMLStr).replaceAll('"', '"')
But if you want to add only wrapper, then you don't need to parse source xml, you may past source file to markup as it:
def newXMLStr = new StreamingMarkupBuilder().bind {
List_Wrapper {
mkp.yieldUnescaped srcFile.text
}
}
Finally if you need to put only one List_Wrapper tag, maybe better to do:
new File(updXMLPath) << "<List_Wrapper>${new File(srcXMLPath).text}</List_Wrapper>"
Related
LAST UPDATE: It seems like the problem was related to geomap and not wanting to update, have now rewritten it using jvectormap as that fits my requirement better.
So
Got an application which have two boxes, one contains a bunch of controllers (resolution, region and stuff). It makes a remote call to a second box which then takes that data and extracts a bunch of things, sets up the data then sends to google visualisation.
However, if I use render in the class it works perfectly, can see that it picks up the right variables, and that they look like they do from the start.
Problem is, if I let it run without render, then the gsp page does not reload, and it is displaying the same code as was originally loaded (and actually, the picture that is generated disappears)
Is there a way I should tell the gsp page to reload or similar?
Below is the remotesubmit that works like a charm (if the controller renders output)
<g:formRemote name="mapRepmote" on404="alert('not found!')" update="page-body"
url="[controller: 'mapren', action:'show']">
<g:if test="${listreg == 'true'}">
Regulation: <g:select name="regsel" from="${reglist}" value="${regreq}" />
</g:if>
<g:else>
Regulation: ${regreq}
</g:else>
Resolution: <g:select name="ressel" from="${reslist}" value="${resreq}" />
Region: <g:select name="mapsel" from="${maplist}" value="${mapreq}" />
<div id="bupdate"><Button type="submit">Update</Button></div>
</g:formRemote>
Edit: What on earth
So been playing around and get the same results over and over again.
So the show action from the mapren controller does seem to be called. I can see the calls to the db layer and all. And if I add three render statements I can see that the requests are coming in.
def show(String regsel, String mapsel, String ressel) {
String mapcode
switch (mapsel) {
case "World":
mapcode="world"
break
case "Europe":
mapcode=150
break
case "Asia":
mapcode=140
break
case "Africa":
mapcode=002
break
case "Central Ameirca":
mapcode=017
break
case "Pacific":
mapcode=035
break
default:
mapcode="world"
}
def restem = ressel.split('x')
String mwidth = restem[0]
String mheight = restem[1]
render "I was asked to show reg: ${params.regsel} <BR>map: ${params.mapsel}<BR>Resolution ${params.ressel}<BR>"
render "will generate map for ${regsel} on code ${mapcode} resolutio"
render "I will ${mwidth} and ${mheight}"
def query = Regstat.where {
(reg==regsel)
}
def regcolumns = [['string', 'Country'],['number', regsel + 'Status']]
def results = query.list(sort:"lupdate")
def regdata = []
results.each {
regdata << [it.country.countryname,it.status]
}
def RegColors = ['0xF0F0F0','0x66CCFF','0x0000FF','0xCC66FF','0x9900CC','0x7D7D7D']
[reg_columns: regcolumns, reg_data: regdata,reg_colors: RegColors, regioncode: mapcode, wwidth: mwidth, wheight: mheight]
}
}
But if I remove the render calls, I would have expected that the show.gsp would get loaded?
But no such luck.
Have attached the show.gsp file. Note, it does is generated when index does a against it to generate the first geomap.
<%# page import="org.grails.plugins.google.visualization.util.DateUtil" %>
<html>
<head>
<script src="http://maps.google.com/maps?file=api&v=2&key=ABCDEFG" type="text/javascript"></script>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
</head>
<body>
<script type="text/javascript">
function selectHandler(e) {
alert('A table row was selected');
}
</script>
<gvisualization:geoMap elementId="page-body" showLegend="${false}" region="${regioncode}" width="${wwidth}" height="${wheight}" colors="${reg_colors}" columns="${reg_columns}" data="${reg_data}" />
</body>
</html>
OK, partial answer, but one step forward a couple back:)
So moved it around and ended up creating a straight forward static version of mapren which have a controller (staticmapren) and a template (_mapdisp). These do seem to work correctly, every time a request comes in, the page now updates correctly with text.
Problem is that the geomap is only displayed first time around.
Was fighting with this quite a lot, then realised that maybe (just maybe) the javascript console might have something to say about this...
Yes it does as it turns out...
Uncaught RangeError: Maximum call stack size exceeded
Red herring: Well, maybe, seems like that one comes up with or without reloading. It happens after about 40 seconds, so still dont have a clue why the map only turns up the first time
My problem is, what on earth can I do about this, could I potentially destroy the object and get a new one each time.
The simplified version of the controller is:
class StaticmaprenController {
def index() {
render "I am an index"
}
def show(String regsel, String mapsel, String ressel) {
String mapcode
mapcode="world"
def restem = ressel.split('x')
String mwidth = restem[0]
String mheight = restem[1]
//render "I was asked to show reg: ${params.regsel} <BR>map: ${params.mapsel}<BR>Resolution ${params.ressel}<BR>"
//render "will generate map for ${regsel} on code ${mapcode} resolutio"
//render "I will ${mwidth} and ${mheight}"
def regcolumns = [['string', 'Country'],['number', regsel + ' Status']]
def RegColors = ['0xF0F0F0','0x66CCFF','0x0000FF','0xCC66FF','0x9900CC','0x7D7D7D']
def regdata = [['UK','3'],['United States','2'],['Russia','4']]
String content = g.render (template:"mapdisp", model:[reg_columns: regcolumns, reg_data: regdata,reg_colors: RegColors, regioncode: mapcode, wwidth: mwidth, wheight: mheight])
render content
[reg_columns: regcolumns, reg_data: regdata,reg_colors: RegColors, regioncode: mapcode, wwidth: mwidth, wheight: mheight]
}
}
And the _mapdisp template
Going to elementId="page-body" <BR>
Testing some stuff showLegend="${false}" <BR>
Will do region="${regioncode}" <BR>
Lets go width="${wwidth}" and height="${wheight}"<BR>
And these are the Beutiful colours colors="${reg_colors}" <BR>
Now columns columns="${reg_columns}"<BR>
And the data="${reg_data}"<BR>
<script type="text/javascript">
function selectHandler(e) {
alert('A table row was selected');
}
</script>
<gvisualization:geoMap elementId="geomap2" showLegend="${false}" region="${regioncode}" width="${wwidth}" height="${wheight}" colors="${reg_colors}" columns="${reg_columns}" data="${reg_data}" />
</body>
<div id="geomap2"></div>
</html>
And to get geomap and google visualisation you will need to install the api, and do some fix with raw (Google Visualization API. Graphs are not displaying in gsp pages)
I have also loaded the api in the main body of the page.
(Adding the following lines)
<%# page import="org.grails.plugins.google.visualization.util.DateUtil" %>
<!DOCTYPE html>
<html>
<head>
<meta name="layout" content="genmap-desk"/>
<script src="http://maps.google.com/maps?file=api&v=2&key=ABCDEFG" type="text/javascript"></script>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
Any suggestions what I can do about Maximum call stack?
After building a Google Dart web app in Dart Editor (the Pub Build (Generates JS) option) the folder layout is like this. My app imports both dart:html and dart:async but It seems I can upload everything but the $sdk folder to my server and the app will run fine in both Dartium and in other browsers. Is there some reason I need to upload the $sdk folder, and what is it for? Tried googling but I see no answer, thanks in advance!
Edit: Here's a working example of my project from DartEditor 1.5.8 and below is the code for it.
hexclock.dart:
import 'dart:html';
import 'dart:async';
DateTime theTime;
String theHour, theMinute, theSecond;
Timer theTimer;
void main() {
theTimer = new Timer.periodic(new Duration(seconds: 1), getTime);
}
void updateColours(){
String bgcol = "#" + theHour + theMinute + theSecond;
querySelector("body").style.backgroundColor = bgcol;
}
void printTime() {
querySelector("#hour").text = theHour;
querySelector("#minute").text = theMinute;
querySelector("#second").text = theSecond;
}
void getTimeInit(){
theTime = new DateTime.now();
theHour = "${checkZero(theTime.hour)}";
theMinute = "${checkZero(theTime.minute)}";
theSecond = "${checkZero(theTime.second)}";
printTime();
updateColours();
}
void getTime(Timer t){
theTime = new DateTime.now();
theHour = "${checkZero(theTime.hour)}";
theMinute = "${checkZero(theTime.minute)}";
theSecond = "${checkZero(theTime.second)}";
querySelector("#title").style.opacity = "0";
querySelector("#clock").style.opacity = "1";
printTime();
updateColours();
}
String checkZero(int anInt){
if (anInt < 10)
return "0${anInt}";
else
return "${anInt}";
}
hexclock.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>HexClock</title>
<script async type="application/dart" src="hexclock.dart"></script>
<script async src="packages/browser/dart.js"></script>
<link href='http://fonts.googleapis.com/css?family=Droid+Sans+Mono' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="hexclock.css">
</head>
<body>
<div id="title" class="centre">hexclock</div>
<div id="clock" class="centre">#<span id="hour"> </span><span id="minute"> </span><span id="second"> </span></div>
</body>
</html>
pubspec.yaml:
name: HexClock
description: A sample web application
dependencies:
browser: any
In the pub source code I found this:
// "$sdk" is a pseudo-package that allows the dart2js transformer to find
// the Dart core libraries without hitting the file system directly. This
// ensures they work with source maps.
var libPath = path.join(sdk.rootDirectory, "lib");
var sdkSources = listDir(libPath, recursive: true)
.where((file) => path.extension(file) == ".dart")
.map((file) {
var idPath = path.join("lib",
path.relative(file, from: sdk.rootDirectory));
return new AssetId('\$sdk', path.toUri(idPath).toString());
});
I don't know if this matches exactly what you're seeing, but my guess is that it's related. This would in theory allow client-side debugging even through SDK functions, which could be very useful.
Basically the entire build folder is intended to be deployed.
There are some redundant files like the *.dart.pecompiled.js which are only necessary for CSP environments (Chrome App for example).
I think there was a recent change so that these files are not generated anymore.
There might be other things redundant too but I haven't seen any information about it yet.
You could try with a Dart 1.6 release (stable should be out) and check if this was dropped or if there has to be another explanation.
I use always bleeding_edge which is currently 1.7+.
Another explanation is that this is only created when you build in debug mode.
DartEditor does this by default.
Try pub build from the command line to see if it is still generated.
I am setting page titles dynamically, based on the on a property in the page's model. Sometimes that property contains html tags, such as <i>Article Title</i>. When the property contains HTML tags, they are showing in the page title. I tried surrounding the property with #Html.Raw, but it didn't help. How can I make sure the tags don't show?
Code:
<head>
<title>#Html.Raw(Model.Title)</title>
</head>
Working code based on #Santiago's answer:
<head>
#{
string titleRaw = Model.Title;
string htmlTag = "<[^>]*>";
Regex rgx = new Regex(htmlTag);
string titleToShow = rgx.Replace(titleRaw, blank);
}
<title>#titleToShow</title>
</head>
Could you try to do it with regular expressions?
<[^>]*>
Took that from:
Regular expression to remove HTML tags from a string
String target = someString.replaceAll("<[^>]*>", "");
Assuming your non-html does not contain any < or > and that your input
string is correctly structured.
A more complete explanation is available in above SO link
I'm trying to write a Grails custom tag that (among other things) triggers inclusion of a resource, so something like <myTags:view name="foo"/> would load, say, js/views/foo.js. And I want it loaded with disposition: 'head'.
I could use <r:external/>, but that wouldn't put it in the <head>, it would just produce an inline <script/> tag. And I could use <r.script/>, but that doesn't let me reference a path; I'd have to have my custom tag read the file and dump it to out.
Now, if foo.js was its own module, I could do something like: r.require([module: 'foo']), but it's not; part of the point of this is that I don't want to have to declare all of these files in ApplicationResources.groovy. But maybe I could have ApplicationResources.groovy create the modules programmatically, by reading through the available files -- is that possible? Or is there a better way?
I ended up going in the direction of having ApplicationResources.groovy create modules programmatically, so the custom tag can use <r:require/>.
The idea is, for each Backbone view, under web-app/myApp/views, there's a Backbone view in a .js file, and a Handlebars template in a .handlebars file (with the same name, by convention). The .handlebars file gets declared as an ordinary module, but gets precompiled by the Handlebars-Resources plugin.
Some code in ApplicationResources.groovy finds all the views and creates corresponding resource modules:
GrailsApplication grailsApplication = Holders.getGrailsApplication()
File viewsDir = grailsApplication.parentContext.getResource("myApp/views").file;
if (viewsDir.exists() && viewsDir.isDirectory() && viewsDir.canRead()) {
String[] viewsJS = viewsDir.list().findAll { name ->
name.endsWith("View.js")
}
String[] views = viewsJS.collect { name ->
name.substring(0, name.length() - ".js".length())
}
for (view in views) {
"${view}" {
dependsOn 'backbone', 'backbone_relational', 'handlebars'
resource url: "dpg/views/${view}.handlebars",
attrs: [type: 'js'],
disposition: 'head'
resource url: "dpg/views/${view}.js",
disposition: 'head'
}
}
}
Then the taglib:
class ViewsTagLib {
static namespace = "myApp"
def view = { attrs ->
r.require(module: "${attrs.name}View")
out << "<${attrs.tagName} id='${attrs.id}'></${attrs.tagName}>"
}
}
Invoking it in a GSP:
<myApp:view tagName="div" name="foo" id="foo1"/>
<myApp:view tagName="div" name="foo" id="foo2"/>
Produces:
<html>
<head>
...
<!--
Automagically generated modules (included only once).
Should put these in the same bundle, but handlebars-resources
gets confused.
-->
<script src="/myApp/static/bundle-bundle_fooView_handlebars.js"
type="text/javascript" ></script>
<script src="/myApp/static/bundle-bundle_fooView_head.js"
type="text/javascript" ></script>
</head>
<body>
...
<div id="foo1"></div> <!-- backbone placeholder for 1st view instance-->
<div id="foo2"></div> <!-- backbone placeholder for 2nd view instance-->
</body>
</html>
It's not pretty but the mess is mostly hidden, and it should cut down considerably on boilerplate and on opportunities to forget to add magic strings to multiple files.
I'm reading an HTML file from a POST response and parsing it with XMLSlurper. The textarea node on the page has some HTML code put into it (non-urlencoded - not my choice) and when I read that value, Groovy strips all the tags.
Example:
<html>
<body>
<textarea><html><body>This has html code for some reason</body></html></textarea>
</body>
</html>
When I parse the above and then find(...) the "textarea" node, it returns to me:
This has html code for some reason
and none of the tags. How do I keep the tags?
I think you're getting the right data, but printing it out wrong... Can you try using StreamingMarkupBuilder to convert the node back to a piece of xml?
def xml = '''<html>
| <body>
| <textarea><html><body>This has html code for some reason</body></html></textarea>
| </body>
|</html>'''
def ta = new XmlSlurper().parseText( xml ).body.textarea
String content = new groovy.xml.StreamingMarkupBuilder().bind {
mkp.yield ta.children()
}
assert content == '<html><body>This has html code for some reason</body></html>'