Use a String as an E4X Expression in AS3? - regex

I need to use a string to access nodes and attributes in XML using E4X. It would be ideal to have this scenario (with XML already loaded):
var myXML:XML = e.target.data;
var myStr:String = "appContent.bodyText.(#name == 'My Text')";
myXML.myStr = "New Value for bodyText node where attribute('name') is equal to 'My Text'";
I ultimately need to set new values to an XML document using strings as E4X expressions.

As noted above:
I figured out a workaround
Take the string of the E4X path you want to target
Pull the E4X path and compare it to your target path
If the two are equal, do what you will with that node/attribute
It's a hack, but it works. You could even parse the XML and populate an array with the target string and the target node, then you could just access it through an item in the array. This is expandable in many ways. As long as everything is set up for proper garbage collection, you'll be okay.

Related

Terraform Splat Expression Giving "Invalid template interpolation value"

I am using data sources in Terraform to fetch a list of ids of my security groups as such:
data "aws_security_groups" "test" {
filter {
name = "group-name"
values = ["the-name"]
}
}
output "security_group_id" {
value = "The id is ${data.aws_security_groups.test.ids[*]}"
}
However, this is giving me the following error:
Error: Invalid template interpolation value
on main.tf line 11, in output "security_group_id":
11: value = "The id is ${data.aws_security_groups.test.ids[*]}"
|----------------
| data.aws_security_groups.test.ids is list of string with 1 element
Cannot include the given value in a string template: string required.
But if I use data.aws_security_groups.test.ids[0] instead it displays the ID.
Can someone help me to display the list of IDs?
First, I want to note that you don't necessarily need to combine this list with a string message at all if you don't want to, because Terraform will accept output values of any type:
output "security_group_ids" {
value = data.aws_security_groups.test.ids
}
If having them included as part of a bigger string is important for your underlying problem then you'll need to make a decision about how you want to present these multiple ids in your single string. There are various different ways you could do that, depending on what you intend to do with this information.
One relatively-straightforward answer would be to make the string include a JSON representation of the list using jsonencode, like this:
output "security_group_id_message" {
value = "The ids are ${jsonencode(data.aws_security_groups.test.ids)}"
}
If you want a more human-friendly presentation then you might prefer to use a multi-line string instead, in which case you can customize the output using string templates.
output "security_group_id_message" {
value = <<-EOT
The ids are:
%{ for id in data.aws_security_groups.test.ids ~}
- ${id}
%{ endfor ~}
EOT
}
Or, for an answer somewhere in between, you could use join to just concatenate the values together with a simple delimiter, like this:
output "security_group_id_message" {
value = "The ids are ${join(",", data.aws_security_groups.test.ids)}"
}
Note that I removed the [*] from your reference in all of these examples, since it isn't really doing anything here: data.aws_security_groups.test.ids is already an iterable collection, and so is compatible with all of the language features I used in the examples above.
IIRC the provider considers this ids attribute to be a set of strings rather than a list of strings, and so that [*] suffix could potentially be useful in other situations to force converting the set into a list if you need it to be typed that way, although if that is your intent then I'd suggest using one of the following instead so that it's clearer to a future reader what it does:
sort(data.aws_security_groups.test.ids) (if it being in lexical order is important to the behavior; Terraform uses lexical sorting by default anyway, but calling sort is a good prompt to a reader unfamiliar with Terraform to look up that function to see what the actual sort order is.)
tolist(data.aws_security_groups.test.ids) (functionally equivalent to sort above when it's a set of strings, but avoids the implication that the specific ordering is important, if all that matters is that it's a list regardless of the ordering)

Does #DynamoDBAttribute support document paths in the attribute name?

I've checked the DynamoDB documentation, and I can't find anything to confirm or deny whether this is allowed.
Is it valid to use a Document Path for the attributeName of #DynamoDBAttribute, as in this code snippet?
#DynamoDBDocument
public class MyClass {
#DynamoDBAttribute(attributeName="object.nestedObject.myAttribute")
private String myAttribute;
.
.
.
// Getters & Setters, etc
}
Edit: Just to be clear, I am specifically trying to find out whether document paths are valid in the #DynamoDBAttribute Java annotation as a way to directly access a nested value. I know that document paths work in general when specifying a query, but this question is specifically about DynamoDBMapper annotations.
Yes, the attribute name can have Dot on it. However, in my opinion, it is not recommended to have Dot on attribute name. Usually, the Dot will be used to navigate the tree in Map attribute.
The following are the naming rules for DynamoDB:
All names must be encoded using UTF-8, and are case-sensitive.
Table names and index names must be between 3 and 255 characters long,
and can contain only the following characters:
a-z
A-Z
0-9
_ (underscore)
(dash)
. (dot)
Attribute names must be between 1 and 255 characters long.
Accessing Map Elements:-
The dereference operator for a map element is . (a dot). Use a dot as
a separator between elements in a map:
MyMap.nestedField
MyMap.nestedField.deeplyNestedField
I can create the item with attribute name containing Dot and query the item using FilterExpression successfully.
It works similarly in all language AWS SDKs. As long as data type is defined as String, it would work as expected.
Some JS examples:-
Create Item:-
var table = "Movies";
var year = 2017;
var title = "putitem data test 2";
var dotAttr = "object.nestedObject.myAttribute";
var params = {
TableName:table,
Item:{
"yearkey": year,
"title": title,
"object.nestedObject.myAttribute": "S123"
},
ReturnValues : 'NONE'
};
Update:-
It works fine with #DynamoDBAttribute annotation as well.
private String dotAttr;
#DynamoDBAttribute(attributeName = "object.nestedObject.myAttribute")
public String getDotAttr() {
return dotAttr;
}
It is not possible to reference a nested path using the attribute name in a #DynamoDBAttribute. I needed to use a POJO type with an added#DynamoDBDocument annotation to represent each level of nesting.

CFML using StructFindValue() to find and replace string values inside of a structure

Question: How can I use the path value that StructValueFind() returns to assign a new value to the key path points to?
I'm looking to search all values in a structure for a specific string and then replace that string with a different value.
I am able to find all occurrences of the string I'm searching for using StructFindValue() which returns an array of structures with the keys key, owner, and path. I would assume that the path would allow me to set a new value/replace the found string.
According to Adobe's CFML 9 documentation for StructFindValue(), the path value is...
Path: string which could be used to reach the found key
But I can't find anywhere how to use the value of path to reach the found key, and specifically assign a new value to that key.
You shouldn't need to mess around with the path: the result from structFindValue() returns a direct reference to the sub struct in question already (in the owner key).
So this sort of thing should do the trick:
<cfscript>
st = {
top={
middle1={lower1="value1",lower2="value2"},
middle2={lower3="value3",lower4="value4"}
}
};
writeDump(st);
value = structFindValue(st, "value3");
writeDump(value);
value[1].owner[value[1].key] = "new value";
writeDump(st);
</cfscript>

AutoHotkey RegExReplace with math

I am trying to change all instances of a number in an xml file. The constant 45 should be added to the number.
Temp is the following text:
<rownum value="1">
<backupapplication>HP Data Protector</backupapplication>
<policy>AUTDR12_Daily</policy>
<policytype>FileSystem</policytype>
<dataretained>31</dataretained>
<fullbackup>7</fullbackup>
<backuptime>0.17</backuptime>
<retentionperiod>Short</retentionperiod>
<peakmbps>11</peakmbps>
<backupcategory>Fulls & Fulls</backupcategory>
</rownum>
<rownum value="2">
<backupapplication>HP Data Protector</backupapplication>
<policy>AUTP_Appl_Monthly</policy>
<policytype>FileSystem</policytype>
<dataretained>268</dataretained>
<fullbackup>91</fullbackup>
<backuptime>2.31</backuptime>
<retentionperiod>Long</retentionperiod>
<peakmbps>12</peakmbps>
<backupcategory>Fulls & Fulls</backupcategory>
</rownum>
I tried the following code:
NeedleRegEx = <rownum value="(\d+)">
Replacement = <rownum value="($1+45)">
Temp := RegExReplace(Temp, NeedleRegEx, Replacement)
But this changes it into
<rownum value="1+45">
while I want
<rownum value="46">
How do I do this in AutoHotKey?
RegEx aren't designed to evaluate mathematical expressions. There are some languages, in which you can use a replacing function that can do dynamic replacements (e.g. JavaScript). But no such luck in AHK.
Using RegEx for the purpose of parsing XML documents isn't good practice anyway. I suggest using an XML parser instead. For AHK, you can utilize a COM object of MSXML2.DOMDocument. Here's an example (and further references) of how to use it: http://www.autohotkey.com/board/topic/56987-com-object-reference-autohotkey-v11/page-2#entry367838.
What you want to do is parse your XML to a DOM document and loop over every rownum tag. Now, you can retrieve the value attribute, increment it, and overwrite the attribute with the new value.
Update
To the code you've posted in the comments: There were some minor mistakes and one big mistake. The big mistake was trying to parse non-valid XML. You can check your XML files by feeding them to a formatter/validator. The loadXml()method will return false if there was a parsing error. The method obj.saveXML() does not exist. If you want to retrieve the document's string representation, simply access its xml property: obj.xml. If you want to save it to a file, there's the built-in method save(filepath).
Here's my suggestion for a clean approach (yes, you CAN use meaningful variable names!):
doc := ComObjCreate("MSXML2.DOMDocument.6.0")
if(!doc.loadXml(xmlString)) {
msgbox % "Hey! That's no valid XML!"
ExitApp
}
rownums := doc.getElementsByTagName("rownum")
Loop % rownums.length
{
rownum := rownums.item(A_Index-1)
value := rownum.getAttribute("value")
value += 45
rownum.setAttribute("value", value)
}
doc.save("myNewFile.xml")

How to read semicolon separated certain values from a QString?

I am developing an application using Qt/KDE. While writing code for this, I need to read a QString that contains values like ( ; delimited)
<http://example.com/example.ext.torrent>; rel=describedby; type="application/x-bittorrent"; name="differentname.ext"
I need to read every attribute like rel, type and name into a different QString. The apporach I have taken so far is something like this
if (line.contains("describedby")) {
m_reltype = "describedby" ;
}
if (line.contains("duplicate")) {
m_reltype = "duplicate";
}
That is if I need to be bothered only by the presence of an attribute (and not its value) I am manually looking for the text and setting if the attribute is present. This approach however fails for attributes like "type" and name whose actual values need to be stored in a QString. Although I know this can be done by splitting the entire string at the delimiter ; and then searching for the attribute or its value, I wanted to know is there a cleaner and a more efficient way of doing it.
As I understand, the data is not always an URL.
So,
1: Split the string
2: For each substring, separate the identifier from the value:
id = str.mid(0,str.indexOf("="));
value = str.mid(str.indexOf("=")+1);
You can also use a RegExp:
regexp = "^([a-z]+)\s*=\s*(.*)$";
id = \1 of the regexp;
value = \2 of the regexp;
I need to read every attribute like rel, type and name into a different QString.
Is there a gurantee that this string will always be a URL?
I wanted to know is there a cleaner and a more efficient way of doing it.
Don't reinvent the wheel! You can use QURL::queryItems which would parse these query variables and return a map of name-value pairs.
However, make sure that your string is a well-formed URL (so that QURL does not reject it).