groovy rename node issue using xmlSlurper - groovy

i have a xml like below where i just need to rename the node name to another.
<a x=1>
<b>c</b>
</a>
and i want to change it to
<p:a x=1>
<b>c</b>
</p:a>
i need to do it using xmlSlurper so how do i do it? how can i do the node rename. Does it need to rewrite the whole xml into another document etc? or can i do it within the document?
def xmlDoc = new XmlSlurper(false,false).parse('my.xml')

First you need to fix your XML. The value for attribute x needs quotes:
<a x="1">
<b>c</b>
</a>
Then to rename the root node:
xmlDoc.replaceNode {
'p:a'(it.children())
}

XmlSlurper reads XML into an object structure. Once you read it in, you can do whatever you want with it, but XmlSlurper has nothing to do with that.
Use MarkupBuilder to write out XML from that read-in object structure.

Related

Does heist support substituting (strings / JSON) into an arbitrary location within a template?

Regarding heist, I've got a template such as:
<script>
var json = ???;
</script>
<h1>Example</h1>
Is there a way to substitute the ??? string with another string?
I think the following function might be the solution https://hackage.haskell.org/package/heist-1.0.1.0/docs/Heist-Splices-Json.html#v:bindJson but I have difficulty understanding that function and or what markup to use in the template.
No. You cannot substitute anything inside a <script> tag because the text inside a script tag is not treated as HTML. It's treated as plain text. If this was not done, you wouldn't be able to write JS code like if ( x < 42 ) because the less than would get treated as the beginning of a tag.

In Play Framework 1.2.x, how to use a render arg value in a path expression?

Let's say that I have a renderArg named xyz. In the groovy template, what's the syntax for using the value of the renderArg in a path expression?
For example:
href="##{'/public/stylesheets/whatever/${xyz}.css'}"
The above fails with a template compilation error (which is what I expected, really). How can I use the value of the render arg inside the path string?
I'll also need to use the arg in other path expressions (not just for a css file reference).
You cannot do it directly, but there is one workaround:
First you should have defined route to root of the application, for instance:
GET / Application.index
next you can use it in this way:
href="##{Application.index}public/stylesheets/whatever/${xyz}.css"
If you repeat the structure above very often, then you can use custom tag, to do so:
add file /app/views/tags/customlink.html(customlink is name of the tag, you can use another one),
fill the content:
##{Application.index}public/stylesheet/whatever/${_key}.css
You can use it now in this way:
href="#{customlink key:'xyz' /}"
More about custom tags you can read here

expression engine dynamic variable names: {slide_{index}_title}

I am using a simple looping plugin so that my template looks like this:
{exp:loop_plus start="1" end="4" increment="1"}
<h3>{slide_{index}_title}</h3>
{/exp:loop_plus}
However, I am ending up with the following output:
<h3>{slide_1_title}</h3>
<h3>{slide_2_title}</h3>
<h3>{slide_3_title}</h3>
<h3>{slide_4_title}</h3>
Is there any way I can have dynamic variable names like this? I am not looking for alternative methods for building a slider, I simply would like to know if the dynamic variable names like this is possible. Thanks!
I'm assuming that Loop Plus (http://devot-ee.com/add-ons/loop-plus) sets the {index} part, so the question is what is defining {slide_1_title}...?
Assuming you have an entry field or variable with this defined, what you have is correct, but if it's not working, it means there's a parsing order issue.
Let's assume the code you supplied is wrapped in a {exp:channel:entries} tag pair, what happens is EE will try to parse the variable first, so will see: {slide_{index}_title} which doesn't exist. The {exp:loop_plus} add-on will then parse it, converting it to {slide_1_title} (but to late as channel:entries has already tried to parse it), which is what is finally output to the template.
So what you want to ensure is that EE parses {exp:loop_plus} before {exp:channel:entries}, do this using parse="inward" tag:
{exp:loop_plus start="1" end="4" increment="1" parse="inward"}
<h3>{slide_{index}_title}</h3>
{/exp:loop_plus}
This is a global EE parameter that EE uses to control parse order - you won't find it documented under the specific add-on. By adding the parameter, it means this child tag will get parsed before it's parent.
One way you could do it is to declare a preload_replace variable in your template and use it in your custom field name.
So something like:
{preload_replace:my_var_prefix="whatever"}
And then in your loop, you could then use:
{slide_{my_var_prefix}_title}

What is the IForm equivalent to fileAFormOpt?

I want to use runInputPost on an existing form with a file input tag. fileAFormOpt exists for AForms, but how can I do the same with an IForm since there is no fileField type?
I would recommend using lookupFile for that use case.

What is the full syntax of Groovy's GPath expressions?

While trying to parse RSS feeds in Groovy, I found a GPath example using wildcards:
def text = """
<data>
<common-tables>
<table name="address"/>
<table name="phone"/>
</common-tables>
<special-tables>
<table name="person"/>
</special-tables>
<other-tables>
<table name="business"/>
</other-tables>
</data>
"""
def xml = new XmlParser().parse(new ByteArrayInputStream(text.getBytes()))
def tables = xml.'**'.table.findAll{ it.parent().name() ==
"special-tables" || it.parent().name
(from http://old.nabble.com/Q:-Avoiding-XPath---using-GPath-td19087210.html)
It looks like a funny use of the 'spread-dot' operator. I can't find any reference to this on the Groovy site, books, etc.
How does this work, and more importantly, how do you discover this? Is there any XPath to GPath 'Rosetta Stone' out there?
Well, as usual, the best place to find information is in the Groovy source itself.
The result of a parsing is a groovy.util.slurpersupport.GPathResult object.
If you look at the source (plain java file), you'll see that the getProperty(string) method has the following special operators:
".." that returns the parent
"*" that returns all the children
"**" that act as a depth first loop
"#" that is used to access a property
the normal node accessor.
That's all, no other magic keywords for the moment.
All of those strings are treated as properties. None of them are actually operators.
The calls are routed through GPathResult#getProperty which specifically checks for the operators listed in gizmo's answer.

Resources