John Wilson
03/07/2023, 6:31 PMname = "Active_Risk" and set the weight to -2 before saving the changed doc as an xml file?
<?xml version="1.0" encoding="utf-8"?>
<!-- saved with AxiomaPortfolio API 2022.2.0 -->
<STRATEGY xmlns="<http://axiomainc.com/portfolioprecision>" strategy-id="FTDIBase" desc="Frontier">
<OPTIONS>
<ALLOW_GRANDFATHERING/>
</OPTIONS>
<LOCAL_UNIVERSE>
<ASSET_REF name="CSH_USD__" action="include"/>
<GROUP_REF name="AccountBenchmark" action="include"/>
</LOCAL_UNIVERSE>
<OBJECTIVE_TERMS>
<RISK objective-term-id="Active_Risk" benchmark-ref="REBALANCING.BENCHMARK" riskmodel-ref="REBALANCING.RISK_MODEL" set-ref="MASTER">
</RISK>
<LINEAR objective-term-id="Factor_Tilt" group-ref="WW4AxiomaMH.Dividend Yield"/>
<TAX_GAINS objective-term-id="Min_Cap_Gains" weighted="false"/>
<TAX_LIABILITY objective-term-id="Min_Tax_Liability"/>
<TRANSACTION_COST objective-term-id="Min_Transaction_Cost" base-set="MASTER"/>
</OBJECTIVE_TERMS>
<OBJECTIVES active-objective="Default">
<OBJECTIVE objective-id="Default" target="MAXIMIZE">
<OBJECTIVE_TERM_REF name="Min_Cap_Gains" weight="-1.0"/>
<OBJECTIVE_TERM_REF name="Active_Risk" weight="-1.0"/>
<OBJECTIVE_TERM_REF name="Min_Transaction_Cost" weight="-0.25"/>
<OBJECTIVE_TERM_REF name="Factor_Tilt" weight="1.0"/>
</OBJECTIVE>
</OBJECTIVES>sknowlton
03/07/2023, 6:38 PMsknowlton
03/07/2023, 6:38 PM<!---
This function converts XML variables into Coldfusion Structures. It also
returns the attributes for each XML node.
--->
<cffunction
name="ConvertXmlToStruct"
access="public"
returntype="struct"
output="true"
hint="Parse raw XML response body into ColdFusion structs and arrays and return it."
>
<cfargument name="xmlNode" type="string" required="true"/>
<cfargument name="str" type="struct" default="#structNew()#"/>
<!--- Setup local variables for recurse: --->
<cfset var i = 0/>
<cfset var axml = arguments.xmlNode/>
<cfset var atr = ''>
<cfset var astr = arguments.str/>
<cfset var n = ""/>
<cfset var tmpContainer = ""/>
<cfset axml = xmlSearch( xmlParse( arguments.xmlNode ), "/node()" )>
<cfset axml = axml[ 1 ]/>
<!--- For each children of context node: --->
<cfloop from="1" to="#arrayLen( axml.XmlChildren )#" index="i">
<!--- Read XML node name without namespace: --->
<cfset n = replace( axml.XmlChildren[ i ].XmlName, axml.XmlChildren[ i ].XmlNsPrefix & ":", "" )/>
<!--- If key with that name exists within output struct ... --->
<cfif structKeyExists( astr, n )>
<!--- ... and is not an array... --->
<cfif not isArray( astr[ n ] )>
<!--- ... get this item into temp variable, ... --->
<cfset tmpContainer = astr[ n ]/>
<!--- ... setup array for this item beacuse we have multiple items with same name, ... --->
<cfset astr[ n ] = arrayNew( 1 )/>
<!--- ... and reassing temp item as a first element of new array: --->
<cfset astr[ n ][ 1 ] = tmpContainer/>
<cfelse>
<!--- Item is already an array: --->
</cfif>
<cfif arrayLen( axml.XmlChildren[ i ].XmlChildren ) gt 0>
<!--- recurse call: get complex item: --->
<cfset astr[ n ][ arrayLen( astr[ n ] ) + 1 ] = convertXmlToStruct(
axml.XmlChildren[ i ],
structNew()
)/>
<cfelse>
<!--- else: assign node value as last element of array: --->
<cfset astr[ n ][ arrayLen( astr[ n ] ) + 1 ] = axml.XmlChildren[ i ].XmlText/>
</cfif>
<cfelse>
<!---
This is not a struct. This may be first tag with some name.
This may also be one and only tag with this name.
--->
<!--- If context child node has child nodes (which means it will be complex type): --->
<cfif arrayLen( axml.XmlChildren[ i ].XmlChildren ) gt 0>
<!--- recurse call: get complex item: --->
<cfset astr[ n ] = convertXmlToStruct( axml.XmlChildren[ i ], structNew() )/>
<cfelse>
<cfif isStruct( aXml.XmlAttributes ) AND structCount( aXml.XmlAttributes )>
<cfset at_list = structKeyList( aXml.XmlAttributes )>
<cfloop from="1" to="#listLen( at_list )#" index="atr">
<cfif listGetAt( at_list, atr ) CONTAINS "xmlns:">
<!--- remove any namespace attributes --->
<cfset structDelete( axml.XmlAttributes, listGetAt( at_list, atr ) )>
</cfif>
</cfloop>
<!--- if there are any atributes left, append them to the response --->
<cfif structCount( axml.XmlAttributes ) GT 0>
<cfset astr[ '_attributes' ] = axml.XmlAttributes/>
</cfif>
</cfif>
<!--- else: assign node value as last element of array: --->
<!--- if there are any attributes on this element --->
<cfif isStruct( aXml.XmlChildren[ i ].XmlAttributes ) AND structCount(
aXml.XmlChildren[ i ].XmlAttributes
) GT 0>
<!--- assign the text --->
<cfset astr[ n ] = axml.XmlChildren[ i ].XmlText/>
<!---
check if there are no attributes with xmlns: , we dont want namespaces to be in the response
--->
<cfset attrib_list = structKeyList( axml.XmlChildren[ i ].XmlAttributes )/>
<cfloop from="1" to="#listLen( attrib_list )#" index="attrib">
<cfif listGetAt( attrib_list, attrib ) CONTAINS "xmlns:">
<!--- remove any namespace attributes --->
<cfset structDelete(
axml.XmlChildren[ i ].XmlAttributes,
listGetAt( attrib_list, attrib )
)>
</cfif>
</cfloop>
<!--- if there are any atributes left, append them to the response --->
<cfif structCount( axml.XmlChildren[ i ].XmlAttributes ) GT 0>
<cfset astr[ n & '_attributes' ] = axml.XmlChildren[ i ].XmlAttributes/>
</cfif>
<cfelse>
<cfset astr[ n ] = axml.XmlChildren[ i ].XmlText/>
</cfif>
</cfif>
</cfif>
</cfloop>
<!--- return struct: --->
<cfreturn astr/>
</cffunction>
andsknowlton
03/07/2023, 6:38 PM/**
* @param input Data to convert into XML. (Required)
* @param element Used to name the root element. (Required)
* @param attributeMeta Checks for the presence of a key in attributeMeta when rendering the key in input, and writes out the contents as attribute/value pairs for the corresponding key
* @return Returns a string.
* @author Phil Arnold (<mailto:philip.r.j.arnold@googlemail.com|philip.r.j.arnold@googlemail.com>) with modifications by Samuel Knowlton (<mailto:sam@inleague.io|sam@inleague.io>) - removed lcasing and added support for attributeMeta
* @version September 9, 2009 / September 29, 2021
**/
public string function toXML( required input, required string element, struct attributeMeta = {} ) {
var i = 0;
var s = createObject( "java", "java.lang.StringBuilder" ).init()
var s1 = "";
s1 = arguments.element;
if ( right( s1, 1 ) eq "s" ) {
s1 = left( s1, len( s1 ) - 1 );
}
s.append( renderXMLAttribute( arguments.element, arguments.attributeMeta ) );
if ( isArray( arguments.input ) ) {
for ( i = 1; i lte arrayLen( arguments.input ); i = i + 1 ) {
if ( isSimpleValue( arguments.input[ i ] ) ) {
s.append( renderXMLAttribute( s1, attributeMeta ) & arguments.input[ i ] & "</#s1#>" );
}
else {
s.append( toXML( arguments.input[ i ], s1 ) );
}
}
}
else if ( isStruct( arguments.input ) ) {
for ( i in arguments.input ) {
if ( isSimpleValue( arguments.input[ i ] ) ) {
s.append( renderXMLAttribute( i, attributeMeta ) & arguments.input[ i ] & "</#i#>" );
}
else {
s.append( toXML( arguments.input[ i ], i ) );
}
}
}
else {
s.append( xmlFormat( arguments.input ) );
}
s.append( "</#arguments.element#>" );
return s.toString();
}
/**
* renderXMLAttribute
* @hint A totally low-rent way to render out XML attributes (e.g. <foo bar="baz">) by checking for the presence of the key in a "sister struct" containing attribute meta nodes. Can't handle multiple nodes with the same name.
* @return String OPENING attribute only (e.g. just <foo bar="baz">)
*/
public string function renderXMLAttribute( required string key, required struct attributeMeta ) {
var attr = '<#arguments.key#';
if ( attributeMeta.keyExists( arguments.key ) ) {
for ( var metaKey in arguments.attributeMeta[ arguments.key ].keyArray() ) {
attr &= ' #metaKey#="' & arguments.attributeMeta[ arguments.key ][ metaKey ] & '"';
}
}
attr &= '>';
return attr;
}John Wilson
03/07/2023, 6:39 PMsknowlton
03/07/2023, 6:39 PMJohn Wilson
03/07/2023, 6:39 PMsknowlton
03/07/2023, 6:40 PMJohn Wilson
03/07/2023, 6:41 PMsknowlton
03/07/2023, 6:42 PMDaniel Mejia
03/07/2023, 6:47 PMdata = xmlparse(xmldata);
objs = data.strategy.objectives.objective.xmlchildren;
arrayMap( data.strategy.objectives.objective.xmlchildren, function( node ) {
if (node.xmlattributes.name eq "Active_Risk"){
node.xmlattributes.weight = "-2.0";
};
} )sknowlton
03/07/2023, 6:48 PMDaniel Mejia
03/07/2023, 6:48 PMJohn Wilson
03/07/2023, 6:48 PMDaniel Mejia
03/07/2023, 6:49 PMsknowlton
03/07/2023, 6:50 PMJohn Wilson
03/07/2023, 6:51 PMTim
03/07/2023, 6:54 PMXMLSearch(xmlDoc, "//*[local-name()='OBJECTIVE_TERM_REF' and @name='Active_Risk']/@weight")[1].XmlText = "-2";
ToString(xmlDoc);Tim
03/07/2023, 6:55 PMSteve Bryant
03/07/2023, 6:56 PMSteve Bryant
03/07/2023, 6:57 PMTim
03/07/2023, 6:58 PMJohn Wilson
03/07/2023, 6:58 PMDaniel Mejia
03/07/2023, 6:58 PMDaniel Mejia
03/07/2023, 6:59 PMSteve Bryant
03/07/2023, 7:02 PMsknowlton
03/07/2023, 7:02 PMTim
03/07/2023, 7:04 PMJohn Wilson
03/07/2023, 7:13 PMJohn Wilson
03/07/2023, 7:14 PMJohn Wilson
03/07/2023, 7:23 PMconstraints with constraint-id = Global_DNH given the fragment below?
<CONSTRAINTS>
<BUDGET constraint-id="Budget" desc="" enabled="true" use-budget-value="true" unit="CURRENCY"/>
<LIMIT_NAMES constraint-id="Max_Number_Of_Names" desc="" enabled="true" scope="AGGREGATE" grandfather-bounds="true" max="400">
<SET_REF name="MASTER"/>
</LIMIT_NAMES>
<THRESHOLD_BUY_TRADE constraint-id="Threshold_Buy" desc="" enabled="true" scope="ASSET" min="0.05" unit="PERCENT">
<SET_REF name="MASTER"/>
</THRESHOLD_BUY_TRADE>
<MULTI_ASSET_NO_WASH constraint-id="Dual_Listed_Wash_Sales" desc="" enabled="false" scope="AGGREGATE">
<SET_REF name="MASTER"/>
</MULTI_ASSET_NO_WASH>
<LIMIT_BUY constraint-id="Global_DNB" desc="" enabled="true" scope="ASSET" max="0.0" unit="CURRENCY">
<SET_REF name="DonotBuyConstraint"/>
</LIMIT_BUY>
<LIMIT_HOLDING constraint-id="Global_DNH" desc="" enabled="true" scope="ASSET" min="0.0" grandfather-bounds="false" max="0.0" unit="CURRENCY">
<SET_REF name="DonotHoldConstraint"/>
</LIMIT_HOLDING>Tim
03/07/2023, 7:26 PM//*[local-name() = 'CONSTRAINTS']/*[@constraint-id='Global_DNH'], I think.Tim
03/07/2023, 7:28 PM//*[local-name() = TAG_NAME] gets an array of all the given tags in the document. / then goes to a child of that tag. @ is the prefix for an attribute. * is "get all the child tags" just like * is "get all the files" in file path.Tim
03/07/2023, 7:29 PM[...] contain a condition to be evaluated on the tagsTim
03/07/2023, 7:31 PM//* then look for ones called CONSTRAINTS (local-name() = 'CONSTRAINTS'). Then look for the children of that (/*) with an attribute of constraint-id ([@constraint-id='blah'])Tim
03/07/2023, 7:32 PMJohn Wilson
03/07/2023, 7:33 PM