I have the following DXL code:
Module m = current
Column c
for c in m do{ print attrName c "\n" }
When I run it I get a listing of only the column names that are currently visible in the opened DOORS module. How can I get a listing of all column names in the module.
Don't confuse columns with attributes.
Columns are related to representing information, attributes store information. And remember that there are object attributes and module attributes.
That being said: The DXL reference manual has the chapter "for object attributes in module" in chapter 20 "Attributes". It says
for object attributes in module
Syntax
for objAttrName in module do {
...
}
where:
objAttrName is a string variable
module is a variable of type Module
Operation
Assigns the string objAttrName to be each successive attribute that is defined for objects in module.
Example
string objAttrName
for objAttrName in (current Module) do print objAttrName "\n"
Related
I have a rather peculiar problem with IBM Doors, using its DXL language:
I CAN get a variable to the module I want to access:
our_mod = module "<path_including_filename_of_module>"
I can NOT perform any of the usual functions pertaining to modules on that variable, e.g.:
name (our_mod) //or entering the string consisting of path + filename directly)
it gives me the error output: "incorrect arguments for fucntion (name)"
BUT, if I search through the folder containing the module, I can grab it via its filename:
Item x
Item my_module
for x in my_folder do
{
if (name(x) == "<filename>")
{
my_module = x
}
}
THEN I can perform name(my_module) or type (my_module):
returns the filename and "Formal" as expected
But even if I get the module that way, I still can NOT iterate over the objects inside that module like with
Object o
for o in my_module do // ...in all my_module... does not work either, same error msg
{
//Do what I came to do...
}
It just gives me the error message "incorrect arguments for (do)"
If anybody had any idea whatsoever as to what might be causing this, would be much obliged.
thanks and regards
There are several data types in DXL that have something to do with modules, all of them have different access functions (perms). E.g. variables of type Item are good for iterating over "everything in a folder or project". If you want to iterate over objects, you need a variable of type Module. As you already found out, the perm "module (string)" does NOT return data of type Module. It returns either a variable of type bool or of type ModName_ (which is a module reference, not a module), depending on the data type where you assign the result. For details, see e.g. the perms list on Tony Goodman's page at http://www.smartdxl.com/downloads/undoc31.html.
In DXL, make sure that you ALWAYS declare variables with a type, never use Auto-Declare if you want to keep your sanity (if you say print our_mod in your upper example you will find that you got a bool, which of course has neither a name nor a type).
For getting a variable of type Module, you first need to open the module (like in real life :) :)). You can open it using edit, share or read. E.g. like this
Module m = read ("/path/to/my_mod", false /* display */, true /* load standard view */)
if null m then error "could not open the module"
Object o
for o in entire m do {print o."Absolute Number" ""}
close m
Hybris: 6.3.0.0-SNAPSHOT (the behavior is the same with 6.3.0.21)
When exporting impex, we noticed a difference when exporting a non-multivalue Type attribute versus exporting a multivalue Type attribute.
When exporting String attribute data without colon, a non-multivalue attribute can be exported as Experts, while a multivalue attribute can be exported as Experts|Hybris.
When exporting Type with String attribute data with colons (e.g. URL), the colon is escaped with a double backslash (for multivalue only). A non-multivalue attribute can be exported as https://experts.hybris.com, while a multivale attribute can be exported as https\://experts.hybris.com if there is only 1 value or as https\://experts.hybris.com|https\://help.hybris.com if there are 2 values.
How can I stop the export from escaping the colon? Is there a method I can override to change this behavior? I would like to change the result to https://experts.hybris.com|https://help.hybris.com or to "https://experts.hybris.com"|"https://help.hybris.com".
Business Case: We want to copy the URL from the exported impex, but the URL contains double backslashes. The exported impex is not meant to be reimported.
Notes #`: The URLs are stored in a collection (e.g. Product.newAttribute, where newAttribute is a collection of custom types which has a String). So, the Impex header looks something like "INSERT_UPDATE Product;newAttribute(data)"
Notes #2: (UPDATE: Didn't work) Currently, I'm checking if it's possible with a CSVCellDecorator; this is for import only.
Notes #3: Currently, I'm checking if it's possible with AbstractSpecialValueTranslator.
For this specific case, I created a new translator, extending AbstractValueTranslator. Then, I implemented the exportValue method, joining the string data (which are URLs), without escaping them.
public String exportValue(final Object value) throws JaloInvalidParameterException
{
String joinedString = "";
if (value instanceof Collection)
{
final Collection valueCollection = (Collection) value;
if (!valueCollection.isEmpty())
{
final ArrayList<CustomType> list = (ArrayList<CustomType>) valueCollection;
final StringJoiner joiner = new StringJoiner("|");
for (final CustomType customType : list)
{
// data is a URL
joiner.add(customType.getData());
}
// value would be something like "https://experts.hybris.com|https://help.hybris.com"
joinedString = joiner.toString();
}
}
return joinedString;
}
Reference:
Customization: https://help.hybris.com/1808/hcd/ef51040168d743879c015b7de232ce40.html
I think that might not be possible, since the colon is used to separate keys for referenced types. As in
...;catalogVersion(catalog(id),version);...
...;myCatalog:Staged;...
Why not run search/replace on the result?
I am about to write a routine that expands <use> elements such that these elements are replaced by the full DOM tree, as described here
The specs say:
An additional transformation translate(x,y) is appended to the end (i.e., right-side) of the ‘transform’ attribute on the generated ‘g’, where x and y represent the values of the ‘x’ and ‘y’ attributes on the ‘use’ element
But those values for x and y may be given like: 10%, so I have created a tiny helper routine like that:
createLength (value) {
const
l = root.createSVGLength(),
parsed = parseFloat(value),
parsedUnit = value
.replace(parsed.toString(), '')
.replace(/^\s*/m, '')
.replace(/\s*$/m, ''),
//UNITS is a map like:
//{px: SVGLength.SVG_LENGTHTYPE_PX, … }
unit = UNITS.hasOwnProperty(parsedUnit) ?
UNITS[parsedUnit] : UNITS.number
;
l.newValueSpecifiedUnits(unit, parsed);
return l;
}
which successfully creates instances of SVGLength. Later in the code I want to create the bespoken SVGTransform which »is appended to the end[…]«, like this:
const [x,y,width,height] =
['x','y','width','height']
.map(attr => node.getAttribute(attr))
.map(val => this.createLength(val))
;
expanded.transform.baseVal
.appendItem(
root.createSVGTransformFromMatrix(
this.matrix(1,0,0,1,
x.value,
y.value)));
What throws this error in chromium, if the given value for x or y is in percentages:
DOMException: Failed to read the 'value' property from 'SVGLength': Could not resolve relative length.
expanded is a reference which is meant to be the replacement of the <use>, which is not attached to a parent node at the time, when the value is assigned.
What is the mistake here?
Thanks to the comment of #RobertLongson I could finally make it work. Instead of creating a new instance of SVGLength, based on the attribute's string value (obtained by node.getAttribute('x')), I just used node.x.baseVal.value for the matrix.
As the docs say for <svg>.createSVGLength():
Creates an SVGLength object outside of any document trees.
Since percentages are relative to values from parent nodes, it is not possible to convert those to numbers, since there is no scale present.
node.x.baseVal also yields the SVGLength, but that one is »inside of any document trees«, so it is possible to convert from pixel to number.
So i've made an object called "potato", then started a loop to check if something in "_level0" has the name of "_level0.potato". What i think is that since the the things in _level0 are objects instead of strings, the object name can't be recognized as a string, so im guessing i need to find a way to convert the object name to a string or vice versa.
var potato:MovieClip = this.createEmptyMovieClip("potato", this.getNextHighestDepth());
for(objects in _level0){
trace(_level0[objects])
if(_root[objects] == "_level0.potato"){
trace("OMG, i found a potato on level0")
}
}
Your suggestion that the objects are stored as a string is incorrect. If you try using typeof before your
trace(typeof _level0[objects])
you will see that its type is movieclip
and your "_level0.potato" is string
They will not be equal. But you can convert object reference to string using String(...) construct.
And about names. You're confusing names and references. MovieClip object like some others in ac2 have property called _name. In this property name of object is stored like string. But only name, not the full path to its destination.
For your potato mc _name will be equal "potato"
So you could do your search like this
var potato:MovieClip = this.createEmptyMovieClip("potato",this.getNextHighestDepth());
for(objects in _level0){
trace(_level0[objects])
if(_root[objects]._name == "potato"){
trace("OMG, i found a potato on level0")
}
}
I have a dictionary that contains instances of a class. Somehow i can not find a way to change a value (assign new class instance) to dictionary.
For example
Dim t as new Product
'initialize t
if dictionaryP.Exists(keyValue) then
'in the next line i get an error "Object doesn't support this property or method"
dictionaryP.Item(keyValue)=t
else
'no problem with this line...
dictionaryP.Add keyValue, t
end if
Couldn't find any information about using dictionaries in VBA with values that are objects, not just plain strings or integers.
How can i change dictionary value for dictionaries that stores objects (class instances), as it seems that i can not do it using
dictionary.Item(key) = <new Object value> ' as i thought it sould be, from this source
http://www.experts-exchange.com/Software/Office_Productivity/Office_Suites/MS_Office/A_3391-Using-the-Dictionary-Class-in-VBA.html
What am i missing? How can i change dictionary values, if values are objects (not plain values)?
Objects must be assigned using Set. The property .Item is the default property and can therefore be dropped (but does not harm). Try
Set dictionaryP (keyValue) = t