MSBuild XslTransformation Xslt Task example

Goal: Change the connection string of my application while running CodedUI tests. So my dev database is left alone.

Here I’ll post a simple “Hello World” setup to alter a xml to output something else. The xml and xslt example has been taken from w3schools.

When you download this file. It will contain a cmd. It loads up environment variables for msbuild and executes the build.proj.

The build.proj looks like this :


<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<!-- Xml & Xslt Examples have been taken from http://www.w3schools.com/xsl/ -->

<Target Name="Build">
<XslTransformation XslInputPath="transform.xslt" XmlInputPaths="source.xml" OutputPaths="out.html" />
</Target>

</Project>

The output is a html page, just as the w3schools demo.

Hope this is a good starting example for your needs.

 

Xml literals escaping

I am somewhat bias towards C#, but one can admire the xml literals in vb.net.

This is a language feature where you can just add xml to

Dim someXml As XElement = <foo>bla<bar active=”false”/></foo>

But how do you add characters that have some a meaning in xml, like “&” or “<“. Turns out you have two options:

Look up how you should escape it (& => &amp; ) but the editor (vs2013) will show wavy underlines underneath the literal. It will compile do and work as expected.

Embed a literal string

Dim someXml As XElement = <foo>Ampersand <%= “&” %><bar active=”false”/></foo>

this uses a method to embed expressions in xml literals.

First Pull-request created.

Well, it had to happen some day.

I’ve found an issue in a project we are using @ work. I’ve created a fix and I want to share it!.

So this project is hosted on github, and it is indeed simple to add fixes.

Just follow these steps :

  1. Fork the project
  2. Create a feature / fix branch
  3. Apply fix.
  4. Push to github.
  5. View this branch on github
  6. Push the “Create Pull Request” button

It will then show you if it can be merged at all. Add some information and you are done!

better details

The fix.

I’ve created a rather simple fix. We are using the “Fluent.Ribbon” for a modern look and feel. But some of our controls are still winforms. There is nothing wrong with winforms, but a mixture of wpf and winforms is not always ideal.

Anyway, we have a combobox in our ribbon and when a winforms control has focus and you try to open this combobox in your ribbon, it acts up.  repro : 

MainWindow_2015-04-09_11-25-11

We have found this message in the debug window:

System.Windows.Data Error: 8 : Cannot save value from target back to source. BindingExpression:Path=IsDropDownOpen; DataItem=’ComboBox’ (Name=’StyleCbx’); target element is ‘ToggleButton’ (Name=’ToggleButton’); target property is ‘IsChecked’ (type ‘Nullable`1′) NullReferenceException:’System.NullReferenceException: Object reference not set to an instance of an object.
at Fluent.ComboBox.OnDropDownOpened(EventArgs e)
at System.Windows.Controls.ComboBox.OnIsDropDownOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
at MS.Internal.Data.PropertyPathWorker.SetValue(Object item, Object value)
at MS.Internal.Data.ClrBindingWorker.UpdateValue(Object value)
at System.Windows.Data.BindingExpression.UpdateSource(Object value)’

Turns out that the fix was rather simple. The combobox of fluent expected the Keyboard.FocusedElement, to always be non-null.

Well this is not the case when dealing with a mixed technology window. So the fix was created and a pull request has been offered.

 

 

String equals based on Regex C#

I need to compare strings based on what is matched by a regex. So I decided to create a regex to pick the parts of a string that I felt was necessary for consideration for equals. When using a regex and leaving parts of the string outside use “non capturing groups”.   Like “(\d+)(?:st|nd|rd|th)?” with will match a number and optional some postfix like “nd” as in 2nd.

 

public static class StringEqualsRegex
{
    /// <summary>
    /// Equals the strings by regex.
    /// </summary>
    /// <param name="s1">The first string.</param>
    /// <param name="s2">The second string.</param>
    /// <param name="regex">The regex.</param>
    /// <returns><c>true</c> if the captured strings of s1 and s2 match, <c>false</c> otherwise.</returns>
    public static bool EqualsByRegex(this string s1, string s2, Regex regex)
    {   
        /*Extension Method*/
        return EqualStringByRegex(s1, s2, regex);
    }

    /// <summary>
    /// Equals the strings by regex.
    /// </summary>
    /// <param name="s1">The first string.</param>
    /// <param name="s2">The second string.</param>
    /// <param name="regex">The regex.</param>
    /// <returns><c>true</c> if the captured strings of s1 and s2 match, <c>false</c> otherwise.</returns>
    public static bool EqualStringByRegex(string s1, string s2, Regex regex)
    {

        string capturedS1 = GetCapturedString(s1, regex);
        string capturedS2 = GetCapturedString(s2, regex);

        return (capturedS1 != null && capturedS2 != null) && 
            capturedS1.Equals(capturedS2);
    }

    private static string GetCapturedString(string s, Regex regex)
    {
        dynamic match = regex.Match(s);

        if ((match.Success))
        {
            var sb = new StringBuilder();
            for (var i = 1; i <= match.Groups.Count; i++)
            {
                foreach (Capture capture in match.Groups[i].Captures)
                {
                    sb.Append(capture.Value);
                }
            }
            return sb.ToString();
        }

        return null;
    }

} 

.

[wpdm_file id=1]

 

Fritzbox 7270 v3, from German to English annex A

Whoops I bought the German version of the device, so it seems I have the 7270 v3 version.

 

What I’ve done:

You need to get your hand on : “fritz_as_avme_newer” and “fritz_as_annex_a_kernel_args_newer” from “telefonicus” @ http://www.ip-phone-forum.de

The scripts are made to upload as “firmware” but I’ve logged in with telnet to the fritzbox and executed the commands myself. I wanted to see what was happening.

I’m not going to give any kind of support. But these are the 2 scripts:

fritz_as_avme_newer

#! /bin/sh
##################################################################################
# get Kernelversion for further handling (update 2.4<->2.6)
##################################################################################
case `uname -r` in
2.4*)
echo “install: have Kernel 2.4”;
kversion=24
;;
2.6*)
echo “install: have Kernel 2.6”;
kversion=26
;;
*)
exit $INSTALL_OTHER_ERROR
;;
esac
#############################################################################
#
# Set Box to AVME
#
#############################################################################
if [ “${kversion}” = 24 ] ; then
echo “firmware_version avme” > /proc/avalanche/env
else
echo “firmware_version avme” > /proc/sys/urlader/environment
fi
##################################################################################ctlmgr

## Bitte keine “rote Meldung”
major=$(grep tffs /proc/devices)
tffs_major=${major%%tffs}
rm -f /var/flash/fw_attrib
mknod /var/flash/fw_attrib c $tffs_major 87
echo -n “” > /var/flash/fw_attrib
rm -f /var/flash/fw_attrib

## Fehler: Kein Fehler
exit 0

fritz_as_annex_a_kernel_args_newer

#! /bin/sh
##################################################################################
# get Kernelversion for further handling (update 2.4<->2.6)
##################################################################################
case `uname -r` in
2.4*)
echo “install: have Kernel 2.4”;
kversion=24
;;
2.6*)
echo “install: have Kernel 2.6”;
kversion=26
;;
*)
exit $INSTALL_OTHER_ERROR
;;
esac
#############################################################################
#
# Set Box to Annex A
#
#############################################################################
if [ “${kversion}” = 24 ] ; then
echo “kernel_args annex=A” > /proc/avalanche/env
else
echo “kernel_args annex=A” > /proc/sys/urlader/environment
fi
##################################################################################ctlmgr

## Bitte keine “rote Meldung”
major=$(grep tffs /proc/devices)
tffs_major=${major%%tffs}
rm -f /var/flash/fw_attrib
mknod /var/flash/fw_attrib c $tffs_major 87
echo -n “” > /var/flash/fw_attrib
rm -f /var/flash/fw_attrib

## Fehler: Kein Fehler
exit 0

 

Then I’ve followed the recovery procedure of the international version. you’ll need FRITZ.Box_Fon_WLAN_7270_v3.en-de-es-it-fr.05.06.recover-image from ftp://ftp.avm.de/fritz.box/fritzbox.fon_wlan_7270_v3/x_misc/english/

 

Enjoy!