Set multiple attributes on root elemement using web.config transformation - asp.net

In visual studio (web.config transformations) I have a transformation I want to perform which adds two attributes on the root element.
One attrbute works (but not multiple ones).
And I can set multiple attributes on a child element.
I have tried SetAttributes with and without specifying the names of the attributes, no luck.
Ideas??
example
<element xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform" xdt:Transform="SetAttributes" attrOne="One" attrTwo="Two">
<children>
<child name="One" xdt:Transform="SetAttributes" attrOne="One" attrTwo="Two" />
</children>
</element>
desired effect
<element attrOne="One" attrTwo="Two">
<children>
<child name="One" attrOne="One" attrTwo="Two" />
</children>
</element>
The "element" section is really a custom section of the web.config file...like so:
<configuration>
... <element configSource="App_Data\element.config" />
this transformation is meant to be used on the element.config file (using slow cheetah)
Update
This apparently doesn't work either:
<element xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform" xdt:Transform="Replace" attrOne="One" attrTwo="Two">
<children>
<child name="One" attrOne="One" attrTwo="Two" />
</children>
</element>
But this does:
<element xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform" xdt:Transform="Replace" attrOne="One">
<children>
<child name="One" attrOne="One" attrTwo="Two" />
</children>
</element>
As soon as there are more than 1 attribute on the root element it fails

Have you tried a document transform like this that sets multiple attributes at the same time by passing a list of attributes to set to SetAttribute()?
See here form more info.
Specifically: Transform="SetAttributes(comma-delimited list of one or more attribute names)"
<element xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform" xdt:Transform="SetAttributes(attrOne,attrTwo)" attrOne="One" attrTwo="Two">
<children>
<child name="One" xdt:Transform="SetAttributes(attrOne,attrTwo)" attrOne="One" attrTwo="Two" />
</children>
</element>

The document element of a web.config file is <configuration>. In your example, <element> is probably a child of <configuration>. Try:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<element xdt:Transform="SetAttributes" attrOne="One" attrTwo="Two">
<children>
<child xdt:Transform="SetAttributes" name="One"
attrOne="One" attrTwo="Two" />
</children>
</element>
</configuration>

Related

How to use xdt-transform when the Web.config element already contains a different xmlns

Using Visual Studio Web.Config Transforms, I want to include the following line in Web.Debug.Config: <add source="*.amazonaws.com" />
This is my Web.config
<configuration>
<!--
-- More config here
-->
<nwebsec>
<httpHeaderSecurityModule xmlns="http://nwebsec.com/HttpHeaderSecurityModuleConfig.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="NWebsecConfig/HttpHeaderSecurityModuleConfig.xsd">
<securityHttpHeaders>
<content-Security-Policy enabled="true">
<default-src none="true" />
<script-src self="true" unsafeEval="true">
<add source="https://cdnjs.cloudflare.com"/>
</script-src>
<style-src unsafeInline="true" self="true">
<add source="https://cdnjs.cloudflare.com"/>
</style-src>
<img-src self="true">
<add source="data:" />
<add source="*.w3.org"/>
<!-- ******** I want to insert new source here for Dev ******** -->
</img-src>
<object-src none="true" />
<media-src none="true" />
<frame-ancestors none="true" />
<report-uri enableBuiltinHandler="true"/>
</content-Security-Policy>
</securityHttpHeaders>
</httpHeaderSecurityModule>
</nwebsec>
</configuration>
I have done what is suggested here, in Web.Debug.config:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<system.web></system.web>
<nwebsec>
<httpHeaderSecurityModule> <!-- I have remove xmlns=... from this element -->
<securityHttpHeaders>
<content-Security-Policy enabled="true">
<img-src self="true" xdt:Transform="Remove" />
<img-src self="true" xdt:Transform="InsertIfMissing">
<add source="data:" />
<add source="*.w3.org"/>
<add source="*.amazonaws.com" />
</connect-src>
</content-Security-Policy>
</securityHttpHeaders>
</httpHeaderSecurityModule>
</nwebsec>
</configuration>
But the new line is not added, how can I do this?
I think this is because httpHeaderSecurityModule has xmlns attribute but don't know how to solve this issue?
Note that I have removed the xmlns=... from httpHeaderSecurityModule in the transform file, if I include the namespace I get the following syntax error:
The 'http://schemas.microsoft.com/XML-Document-Transform:Transform'
attribute is not declared
I am not sure if there is a better solution but I could not get the transforms working inside httpHeaderSecurityModule (which has xmlns=...) element, according to MS documentation:
The root element of a transform file must specify the
XML-Document-Transform namespace in its opening tag
The only way that I could do this transform was to replace everything above the element which has xmlns, i.e.
<nwebsec xdt:Transform="Remove" />
<nwebsec xdt:Transform="InsertIfMissing">
<httpHeaderSecurityModule xmlns="http://nwebsec.com/HttpHeaderSecurityModuleConfig.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="NWebsecConfig/HttpHeaderSecurityModuleConfig.xsd">
<securityHttpHeaders>
<content-Security-Policy enabled="true">
<default-src none="true" />
<script-src self="true" unsafeEval="true">
<add source="https://cdnjs.cloudflare.com"/>
</script-src>
<style-src unsafeInline="true" self="true">
<add source="https://cdnjs.cloudflare.com"/>
</style-src>
<img-src self="true">
<add source="data:" />
<add source="*.w3.org"/>
<!-- ******** I want to insert new source here for Dev ******** -->
</img-src>
<object-src none="true" />
<media-src none="true" />
<frame-ancestors none="true" />
<report-uri enableBuiltinHandler="true"/>
</content-Security-Policy>
</securityHttpHeaders>
</httpHeaderSecurityModule>
</nwebsec>
One alternative could be to use a separate config file instead of a full transformation. You can do something like this:
<nwebsec xdt:Transform="Remove" />
<nwebsec xdt:Transform="InsertIfMissing">
<httpHeaderSecurityModule configSource="NWebsec.config" >
</httpHeaderSecurityModule>
</nwebsec>
Unfortunately you cannot directly use the nwebsec elemente (see here why).

How to replace attributes in XML transforms without the name attribute

I am using SlowCheetah to transform my Log4Net files when I publish. However, it can't seem to distinguish between the attributes in different appender sections.
My Log4Net.config looks basically like this:
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
<to value="DevEmail" />
<from value="DevEmail" />
<subject value="Dev Warning" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="Time: %date%newlineHost: %property{log4net:HostName}%newlineClass: %logger%newlineUser: %property{user}%newlineMessage: %message%newline%newline%newline" />
</layout>
<threshold value="WARN" />
</appender>
<appender name="FatalSmtpAppender" type="log4net.Appender.SmtpAppender">
<to value="DevEmail" />
<from value="DevEmail" />
<subject value="Dev Fatal" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="Time: %date%newlineHost: %property{log4net:HostName}%newlineClass: %logger%newlineUser: %property{user}%newlineMessage: %message%newline%newline%newline" />
</layout>
<threshold value="FATAL" />
</appender>
</log4net>
And my transform file looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<log4net xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
<to value="ProductionEmail" xdt:Transform="SetAttributes" />
<from value="ProductionEmail" xdt:Transform="SetAttributes" />
<subject value="Production Warning" xdt:Transform="SetAttributes" />
</appender>
<appender name="FatalSmtpAppender" type="log4net.Appender.SmtpAppender">
<to value="ProductionEmail" xdt:Transform="SetAttributes" />
<from value="ProductionEmail" xdt:Transform="SetAttributes" />
<subject value="Production Fatal" xdt:Transform="SetAttributes" />
</appender>
</log4net>
The problem is that the transformed config has the same subject attribute value for both appenders; I guess when it hits the SetAttributes it can't tell which tag it's looking for, so it transforms all of them. What it the correct syntax to tell it to only find the elements within the same appender? I assume I need to use the xdt:Locator attribute, but I can't do Match(name) like I do for web.config because these elements don't have a name attribute. The appender element has a name attribute, but I don't know how to tell it to match based on the parent element's name.
I know that I could use replace on the appender node, with the match(Name), but then I would be replacing the entire node, including a bunch of elements such as the layout which I don't want to be transformed (and thus have multiple copy-pastes of the same code, which I would like to avoid).
I found the answer in this MSDN article: http://msdn.microsoft.com/en-us/library/dd465326.aspx.
I needed to use xdt:Locator="Match(name)" on the parent <appender> node, and then xdt:Transform on the child nodes. I had tried this previously but had used xdt:locator="Match(name)" instead of xdt:Locator="Match(name)"... The attribute is case sensitive.

Assigning List of Strings in BPEL

Is there a way to assign a list of strings from input variable to invoke input variable?The problem is that there are multiple inputs in my web service so i am not able to copy the wrapping element in input variable to wrapping variable in invoke variable.Will copy the snippet of the code here :
<assign name="Assign1">
<copy>
<from variable="inputVariable" part="payload"
query="/ns2:process/ns2:dsaName"/>
<to variable="Invoke1_processList_InputVariable"
part="parameters" query="/ns1:processList/dsaName"/>
</copy>
<copy>
<from variable="inputVariable" part="payload"
query="/ns2:process/ns2:linesOfData"/>
<to variable="Invoke1_processList_InputVariable"
part="parameters" query="/ns1:processList/linesOfData"/>
</copy>
<copy>
<from variable="inputVariable" part="payload"
query="/ns2:process/ns2:description"/>
<to variable="Invoke1_processList_InputVariable"
part="parameters" query="/ns1:processList/description"/>
</copy>
<copy>
<from variable="inputVariable" part="payload"
query="/ns2:process/ns2:application"/>
<to variable="Invoke1_processList_InputVariable"
part="parameters" query="/ns1:processList/application"/>
</copy>
</assign>
The problem is that only one is of list type all others are of string type.The XML for this is:
<element name="process">
<complexType>
<sequence>
<element name="dsaName" type="string" minOccurs="0"/>
<element name="linesOfData" type="string" minOccurs="0" maxOccurs="unbounded"/>
<element name="description" type="string" minOccurs="0"/>
</sequence>
</complexType>
</element>
<element name="processResponse">
<complexType>
<sequence>
<element name="result" type="string" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
</element>
</schema>
Looking at your schema, you can use doXSLTransform operation where <xsl:for-each> is used to read the list type (here it's linesOfData) and add each of those elements to Invoke1_processList_InputVariable.

traversing a BPEL array

I need to traverse an array (input to BPEL) in java embed activity and need to generate a response (output variable) of BPEL process.
I am using Jdeveloper and SOA 11g
following is my xsd
<?xml version="1.0" encoding="UTF-8"?>
<schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://xmlns.oracle.com/BPELInpuandOutPutArray_jws/Project1/BPEL_input_output_array" xmlns="http://www.w3.org/2001/XMLSchema">
<element name="process">
<complexType>
<sequence>
<element name="simpleinput" type="string"/>
<element name="arrayofObjects" maxOccurs="unbounded" nillable="true">
<complexType>
<sequence>
<element name="input1" type="string"/>
<element name="input2" type="string"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
<element name="processResponse">
<complexType>
<sequence>
<element name="arrayofObjectsoutput" maxOccurs="unbounded" nillable="true">
<complexType>
<sequence>
<element name="output1" type="string"/>
<element name="output2" type="string"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>
so far I am able to manage for traversing in input array
oracle.xml.parser.v2.XMLElement e1=
(oracle.xml.parser.v2.XMLElement)getVariableData("inputVariable","payload","/client:process/client:arrayofObjects[1]/client:input1");
System.out.println(e1.getFirstChild().getNodeValue());
But my business requirement is to based on some logic set the values in output array.
for this I used following sample code.
for(int i=1; i < 4 ;i++)
{
setVariableData("outputVariable","payload","/client:processResponse/client:arrayofObjectsoutput['i']/client:output1",i);
setVariableData("outputVariable","payload","/client:processResponse/client:arrayofObjectsoutput['i']/client:output2",i);
}
My feeling is array would be created of length 3 and value will be settes(1,1) (2,2) (3,3) but at the output value is only (3,3) .
please tell me how can i achieve the same.
sample code will be appreciated.
The way I did it for a similar situation was to use a transformation to create the first element and then use the bpelx:insertAfter to insert additional array elements and then set them.
<assign name="Assign_2">
<bpelx:insertAfter>
<bpelx:from variable="outputVariable" part="payload"
query="/client:ArrayManipulationProcessResponse/client:arrayofObjectsoutput"/>
<bpelx:to variable="outputVariable" part="payload"
query="/client:ArrayManipulationProcessResponse/client:arrayofObjectsoutput"/>
</bpelx:insertAfter>
<copy>
<from expression="'MyOutput1-Index2'"/>
<to variable="outputVariable" part="payload"
query="/client:ArrayManipulationProcessResponse/client:arrayofObjectsoutput[2]/client:output1"/>
</copy>
<copy>
<from expression="'MyOutput2-Index2'"/>
<to variable="outputVariable" part="payload"
query="/client:ArrayManipulationProcessResponse/client:arrayofObjectsoutput[2]/client:output2"/>
</copy>
</assign>
If proprietary extensions do not work, you can try the standard BPEL approach and use an XSLT script to iteratively construct a result document.
An example is given in the BPEL 2.0 specification, pp 65, look for Iterative document construction.
Basically, the list and the element to add is passed (via the doXSLTransform XPath function) to an XSLT script, which copies the element to add to the list and returns the new document. This is then assigned to a variable.
I feel there is no need to write custom Java code for such a simple task. The following code (BPEL2.0) does the job of copying the values.<assign name="Copy values">
<extensionAssignOperation>
<bpelx:copyList>
<bpelx:from>$inputVariable.payload/ns1:arrayofObjects</bpelx:from>
<bpelx:to>$outputVariable.payload/ns1:arrayofObjectsoutput</bpelx:to>
</bpelx:copyList>
</extensionAssignOperation>
</assign>

Adding runtime-library-path to flex build configuration using ant mxmlc task

I'm trying to build a flex project, linking it to some RLSs. When setting up the project in Flex Builder, the corresponding "build configuration" (that I got by adding -dump-config to the compiler options) generates (among other things) a tag like this :
<runtime-shared-libraries>
<url>some-lib.swf</url>
<url>some-other-lib.swf</url>
</runtime-shared-libraries>
Now, I am trying to build the project using mxmlc ant task, but I can't seem to add any reference to a share-library. I thought something like this would have help, but it didin't:
<!-- Skipping attributes that I don't think are relevant ... -->
<mxmlc ....>
...
<runtime-shared-library-path>
<url rsl-url="some-lib.swf"></url>
<url rsl-url="some-other-lib.swf"></url>
</runtime-shared-library-path>
</mxmlc>
So what could I be missing here ?
Thanks
You will need to specify the path to the SWC of your custom libraries via the "path-element" attribute on the "runtime-shared-library-path" element and define the "rsl-url" in the "url" element which points to the SWF. Note that this is needed for each custom RSL individually.
To achieve this you'll need to unpack the SWC and extract the SWF from it so that the compiler can copy it to the output folder.
There is a comment on a post here that describes how to include the Mate framework as an RSL. I added the interesting part below.
First, you have to extract the SWF from the SWC file yourself.
<macrodef name="create-rsl">
<attribute name="rsl-dir" />
<attribute name="swc-dir" />
<attribute name="swc-name" />
<sequential>
<unzip src="#{swc-dir}/#{swc-name}.swc" dest="#{rsl-dir}" >
<patternset>
<include name="library.swf" />
</patternset>
</unzip>
<move file="#{rsl-dir}/library.swf" tofile="#{rsl-dir}/#{swc-name}.swf"/>
</sequential>
</macrodef>
<target name="extract-rsls">
<!-- Third parties RSLs -->
<create-rsl rsl-dir="${build.rsls.dir}" swc-dir="${lib.dir}" swc-name="mate" />
</target>
Then, you need to put this SWF file as a RSL:
<target name="compile">
<mxmlc file="${src.dir}/MyApplication.mxml" output="${build.dir}/MyApplication.swf" locale="${locale}" debug="false">
<!-- Flex default compile configuration -->
<load-config filename="${flex.frameworks.dir}/flex-config.xml" />
<!-- Main source path -->
<source-path path-element="${src.dir}" />
<runtime-shared-library-path path-element="${lib.dir}/mate.swc">
<url rsl-url="rsls/mate.swf" />
</runtime-shared-library-path>
</mxmlc>
</target>
I guess you are missing the path-element
<runtime-shared-library-path path-element="${FLEX_FRAMEWORK}/framework.swc">
<url rsl-url="framework_3.4.1.10084.swf"/>
<!--<url rsl-url="datavisualization_3.2.0.3958.swf"/>-->
</runtime-shared-library-path>
You may find this xsl useful. You can call it from ant and generate your RSL entries from you .actionScriptProperties file. I hope this helps everyone going through RSL hell!!! See here:
<mxmlc output="${{dist.dir}}/${{inputMXML}}.swf"
file="${{src.dir}}/${{inputMXML}}.mxml"
locale="${{compiler.locale}}"
use-network="${{compiler.use-network}}"
debug="false"
optimize="true"
incremental="false">
<load-config filename="${{FLEX_HOME}}/frameworks/flex-config.xml"/>
<source-path path-element="${{src.dir}}"/>
<!-- Project RSLs -->
<xsl:for-each select="//libraryPath/libraryPathEntry">
<xsl:if test="#linkType = '1'">
<compiler.library-path>
<!-- substring before last '/' -->
<xsl:attribute name="dir">
<xsl:call-template name="substring-before-last">
<xsl:with-param name="list" select="#path" />
<xsl:with-param name="delimiter" select="'/'" />
</xsl:call-template>
</xsl:attribute>
<xsl:attribute name="append">true</xsl:attribute>
<xsl:element name="include">
<xsl:attribute name="name">
<!-- substring after last '/' -->
<xsl:call-template name="substring-after-last">
<xsl:with-param name="string" select="#path" />
<xsl:with-param name="delimiter" select="'/'" />
</xsl:call-template>
</xsl:attribute>
</xsl:element>
</compiler.library-path>
</xsl:if>
</xsl:for-each>
<!-- Framework RSLs. Note: Order is important. Also note: swz comes
first. This is the signed version of the library which once
downloaded can be used cross-domain, possibly saving bandwidth -->
<runtime-shared-library-path path-element="${{FLEX_HOME}}/frameworks/libs/textLayout.swc">
<url rsl-url="textLayout_2.0.0.232.swz"/>
<url rsl-url="textLayout_2.0.0.232.swf"/>
</runtime-shared-library-path>
<runtime-shared-library-path path-element="${{FLEX_HOME}}/frameworks/libs/framework.swc">
<url rsl-url="framework_4.6.0.23201.swz"/>
<url rsl-url="framework_4.6.0.23201.swf"/>
</runtime-shared-library-path>
<runtime-shared-library-path path-element="${{FLEX_HOME}}/frameworks/libs/osmf.swc">
<url rsl-url="osmf_1.0.0.16316.swz"/>
<url rsl-url="osmf_1.0.0.16316.swf"/>
</runtime-shared-library-path>
<runtime-shared-library-path path-element="${{FLEX_HOME}}/frameworks/libs/charts.swc">
<url rsl-url="charts_4.6.0.23201.swz"/>
<url rsl-url="charts_4.6.0.23201.swf"/>
</runtime-shared-library-path>
<runtime-shared-library-path path-element="${{FLEX_HOME}}/frameworks/libs/rpc.swc">
<url rsl-url="rpc_4.6.0.23201.swz"/>
<url rsl-url="rpc_4.6.0.23201.swf"/>
</runtime-shared-library-path>
<runtime-shared-library-path path-element="${{FLEX_HOME}}/frameworks/libs/mx/mx.swc">
<url rsl-url="mx_4.6.0.23201.swz"/>
<url rsl-url="mx_4.6.0.23201.swf"/>
</runtime-shared-library-path>
<runtime-shared-library-path path-element="${{FLEX_HOME}}/frameworks/libs/spark.swc">
<url rsl-url="spark_4.6.0.23201.swz"/>
<url rsl-url="spark_4.6.0.23201.swf"/>
</runtime-shared-library-path>
<runtime-shared-library-path path-element="${{FLEX_HOME}}/frameworks/libs/advancedgrids.swc">
<url rsl-url="advancedgrids_4.6.0.23201.swz"/>
<url rsl-url="advancedgrids_4.6.0.23201.swf"/>
</runtime-shared-library-path>
<runtime-shared-library-path path-element="${{FLEX_HOME}}/frameworks/libs/sparkskins.swc">
<url rsl-url="sparkskins_4.6.0.23201.swz"/>
<url rsl-url="sparkskins_4.6.0.23201.swf"/>
</runtime-shared-library-path>
<runtime-shared-library-path path-element="${{FLEX_HOME}}/frameworks/libs/spark_dmv.swc">
<url rsl-url="spark_dmv_4.6.0.23201.swz"/>
<url rsl-url="spark_dmv_4.6.0.23201.swf"/>
</runtime-shared-library-path>
<!-- Project RSLs -->
<!-- Flex Ant Task Shortcoming. -->
<xsl:for-each select="//libraryPath/libraryPathEntry">
<xsl:if test="#linkType = '4'">
<runtime-shared-library-path>
<xsl:attribute name="path-element">
<xsl:value-of select="#path" />
</xsl:attribute>
<xsl:element name="url">
<xsl:attribute name="rsl-url">
<xsl:value-of select="crossDomainRsls/crossDomainRslEntry/#rslUrl" />
</xsl:attribute>
</xsl:element>
</runtime-shared-library-path>
</xsl:if>
</xsl:for-each>
</mxmlc>

Resources