Windows Vista Forums

xml/xsl to create msbuild files........MSB4097......and an xsl workarounds(??)
  1. #1


    sloan Guest

    xml/xsl to create msbuild files........MSB4097......and an xsl workarounds(??)

    <!-- The xml in question -->

    <?xml version="1.0" encoding="utf-8"?>
    <Project DefaultTargets="AllTargetsWrapper"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <!-- - - -->
    <Target Name="AllTargetsWrapper" xmlns="">
    <Message Text="You just called the Target named 'AllTargetsWrapper'" />
    </Target>
    <!-- - - -->
    <Target Name="Target1" xmlns="">
    <Message Text="You just called the Target named 'Target1'" />
    </Target>
    <!-- - - -->
    <Target Name="Target2" xmlns="">
    <Message Text="You just called the Target named 'Target2'" />
    </Target>
    <!-- - - -->
    <Target Name="Target3" xmlns="">
    <Message Text="You just called the Target named 'Target3'" />
    </Target>
    <!-- - - -->
    </Project>


    <!-- -->




    The backstory of this post is here:
    https://connect.microsoft.com/Visual...he-correct-one

    Basically, there are some msbuild/xml issues.
    The wonderful error you get is:
    error MSB4097: The element <Target> beneath element <Project> may not have a
    custom XML namespace.


    There are some suggestions at the site.
    One is "write out the xml/reload it, then add elements".
    The other one is "use the msbuild object library".
    Neither is especially desirable.


    I only recently found the issue at the connect.microsoft.com site......I put
    in some heavy work creating some lightweight xml and then an xsl transform
    sheet to create my msbuild project file.
    Aka, I just did alot a work before I hit this monkey wrench. :<

    At the top of this post ......there is the (resultant xml from my transform)
    is currently what I'm stuck with.

    The issue are these orphaned
    xmlns=""
    values.


    Because of the bug......(outlined in the URL above)...

    you cannot have this xml (below is a copy from the xml above):
    <Target Name="AllTargetsWrapped" xmlns="">

    AND you cannot do this:
    <Target Name="AllTargetsWrapped"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">


    The end result has to be:


    <?xml version="1.0" encoding="utf-8"?>
    <Project DefaultTargets="AllTargetsWrapper"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <!-- - - -->
    <Target Name="AllTargetsWrapper"> <!-- Emphasis here because there is no
    xmlns value -->
    <Message Text="You just called the Target named 'AllTargetsWrapper'" />
    </Target>
    <!-- - - -->
    <Target Name="Target1">
    <Message Text="You just called the Target named 'Target1'" />
    </Target>
    <!-- - - -->
    <Target Name="Target2">
    <Message Text="You just called the Target named 'Target2'" />
    </Target>
    <!-- - - -->
    <Target Name="Target3">
    <Message Text="You just called the Target named 'Target3'" />
    </Target>
    <!-- - - -->
    </Project>




    ==============

    Here is a very basic (and does-not-do-anything-interesting) example of some
    xml and xsl which creates the issue:

    <!-- START XML -->

    <?xml version="1.0" encoding="utf-8"?>
    <root>
    <demoTargets>
    <demoTarget>
    <targetName>AllTargetsWrapper</targetName>
    </demoTarget>
    <demoTarget>
    <targetName>Target1</targetName>
    </demoTarget>
    <demoTarget>
    <targetName>Target2</targetName>
    </demoTarget>
    <demoTarget>
    <targetName>Target3</targetName>
    </demoTarget>
    </demoTargets>
    </root>


    <!-- END XML -->

    <!-- START XSL-->

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">
    <xsl:strip-space elements="*" />
    <xslutput method="xml" />
    <!-- -->
    <xsl:template match="/">
    <!-- -->
    <Project DefaultTargets="AllTargetsWrapper"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <xsl:comment> -- </xsl:comment>
    <xsl:call-template name="CreateTargetsTemplate"></xsl:call-template>
    <!-- -->
    </Project>
    <!-- -->
    </xsl:template>
    <!-- -->
    <xsl:template name="CreateTargetsTemplate">
    <!-- -->
    <xsl:for-each select="//root/demoTargets/demoTarget">
    <xsl:element name="Target">
    <xsl:attribute name="Name">
    <xsl:value-of select="./targetName" />
    </xsl:attribute>
    <xsl:element name="Message">
    <xsl:attribute name="Text">You just called the Target named
    '<xsl:value-of select="./targetName" />'</xsl:attribute>
    </xsl:element>
    </xsl:element>
    <xsl:comment> -- </xsl:comment>
    </xsl:for-each>
    <!-- -->
    </xsl:template>
    <!-- -->
    </xsl:stylesheet>


    <!-- END XSL-->

    <!-- START DESIRED RESULT -->

    <?xml version="1.0" encoding="utf-8"?>
    <Project DefaultTargets="AllTargetsWrapper"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <!-- - - -->
    <Target Name="AllTargetsWrapper" />
    <!-- - - -->
    <Target Name="Target1" />
    <!-- - - -->
    <Target Name="Target2" />
    <!-- - - -->
    <Target Name="Target3" />
    <!-- - - -->
    </Project>


    <!-- END DESIRED RESULT -->






    <!-- START RESULT1 THAT DOES NOT WORK -->

    <?xml version="1.0" encoding="utf-8"?>
    <Project DefaultTargets="AllTargetsWrapper"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <!-- - - -->
    <Target Name="AllTargetsWrapper" xmlns="" />
    <!-- - - -->
    <Target Name="Target1" xmlns="" />
    <!-- - - -->
    <Target Name="Target2" xmlns="" />
    <!-- - - -->
    <Target Name="Target3" xmlns="" />
    <!-- - - -->
    </Project>

    <!-- END RESULT1 THAT DOES NOT WORK -->

    <!-- START RESULT2 THAT DOES NOT WORK -->


    <?xml version="1.0" encoding="utf-8"?>
    <Project DefaultTargets="AllTargetsWrapper"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <!-- - - -->
    <Target Name="AllTargetsWrapper"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    </Target>
    <!-- - - -->
    <Target Name="Target1"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    </Target>
    <!-- - - -->
    <Target Name="Target2"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    </Target>
    <!-- - - -->
    <Target Name="Target3"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    </Target>
    <!-- - - -->
    </Project>

    <!-- END RESULT2 THAT DOES NOT WORK -->



    If you want to see this issue "in action"........then take the xml and xsl
    above (the slimmed down version xml/xsl pair I have above)
    Transform it, and put the resultant xml in a file called
    "MSBuildXmlIssueTransformOutput.xml"

    Create a .bat file
    And put this in the .bat file

    <!-- START BAT FILE -->

    @echo off
    ECHO Demonstrate MSBuild create Own Xml Issue:
    ECHO .

    @echo on

    set msBuildDir=%WINDIR%\Microsoft.NET\Framework\v3.5
    set msBuildDir=%WINDIR%\Microsoft.NET\Framework\v2.0.50727



    call %msBuildDir%\msbuild /target:AllTargetsWrapper
    "MSBuildXmlIssueTransformOutput.xml" /p:Configuration=Release
    /l:FileLogger,Microsoft.Build.Engine;logfile=MSBuildXmlIssueOutput.log

    set msBuildDir=

    <!-- END BAT FILE -->


    You will see that you get MSBuild issues unless the xml is like "START
    DESIRED RESULT" format above.


    Any hope for this one? I've read the suggestions at connect.microsoft.com
    and it just undermines my efforts I just put in.

    Even if I have to perform two transformations, that is an option...........
    I'm "ok" (skill-wise) with xsl, but thought I would post this issue to
    people alot better at xsl than I am.


    And I appreciate you looking, but comments along the lines of
    "You don't have to use <xsl:element></xsl:element> , you can write it
    shorter using ______________" are especially helpful on this one.
    I'll rework the xsl to be trimmer if I find a workaround...I promise!



    The engines I have available are.

    DotNet Xml/Xsl Libraries, 3.5 Framework.
    Saxon (in a pinch that is) ("C:\Program
    Files\MSBuild\SaxonHE\bin\Transform.exe")
    MSXML2.DOMDocument.6.0




    Thanks for any help.


    I'm probably gonna document some of this over on the connect.microsoft.com
    site as well.......since I went to trouble of creating some samples.





      My System SpecsSystem Spec

  2. #2


    Martin Honnen Guest

    Re: xml/xsl to create msbuild files........MSB4097......and an xslworkarounds(??)

    sloan wrote:

    > <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    > version="2.0">
    You simply need to put your namespace declaration on the xsl:stylesheet
    element, that way it applies to all literal result elements so use

    <xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
    version="2.0">

    instead of what you have above.

    And then you can drop the namespace declaration below:


    > <xsl:template match="/">
    > <!-- -->
    > <Project DefaultTargets="AllTargetsWrapper"
    > xmlns="http://schemas.microsoft.com/developer/msbuild/2003">



    --

    Martin Honnen --- MVP XML
    http://msmvps.com/blogs/martin_honnen/

      My System SpecsSystem Spec

  3. #3


    sloan Guest

    Re: xml/xsl to create msbuild files........MSB4097......and an xsl workarounds(??)


    Martin,

    THANK YOU, it works just as you said.

    I'm posting my basic-setup scenario xml and xsl so future googlers
    (errrr......bingers) will find a basic and working example.

    Again, thank you very much.



    <!-- START XML -->

    <?xml version="1.0" encoding="utf-8"?>
    <root>
    <demoTargets>
    <demoTarget>
    <targetName>AllTargetsWrapper</targetName>
    </demoTarget>
    <demoTarget>
    <targetName>Target1</targetName>
    </demoTarget>
    <demoTarget>
    <targetName>Target2</targetName>
    </demoTarget>
    <demoTarget>
    <targetName>Target3</targetName>
    </demoTarget>
    </demoTargets>
    </root>

    <!-- END XML -->


    <!-- START XSL THAT WORKS VIA INSTRUCTIONS IN PREVIOUS POST -->


    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
    version="2.0">
    <!-- <xsl:strip-space elements="*" /> -->
    <xslutput method="xml" />
    <xsl:variable name="AllTargetsWrapperConstant">
    <xsl:value-of select="'AllTargetsWrapper'" />
    </xsl:variable>
    <!-- -->
    <xsl:template match="/">
    <!-- -->
    <Project DefaultTargets="AllTargetsWrapper"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <xsl:comment> -- </xsl:comment>
    <xsl:call-template name="CreateTargetsTemplate"></xsl:call-template>
    <!-- -->
    <xsl:comment> -- </xsl:comment>
    </Project>
    <!-- -->
    </xsl:template>
    <!-- -->
    <xsl:template name="CreateTargetsTemplate">
    <!-- -->
    <xsl:comment> -- </xsl:comment>
    <xsl:for-each select="//root/demoTargets/demoTarget">
    <xsl:element name="Target">
    <xsl:attribute name="Name">
    <xsl:value-of select="./targetName" />
    </xsl:attribute>
    <xsl:element name="Message">
    <xsl:attribute name="Text">You just called the Target named
    '<xsl:value-of select="./targetName" />'</xsl:attribute>
    </xsl:element>
    <xsl:if test="targetName = $AllTargetsWrapperConstant">
    <xsl:comment> The above special target name will call all targets
    </xsl:comment>
    <xsl:call-template
    name="CreateAllTargetsSpecialTemplate"></xsl:call-template>
    </xsl:if>
    </xsl:element>
    <xsl:comment> -- </xsl:comment>
    </xsl:for-each>
    <!-- -->
    <xsl:comment> -- </xsl:comment>
    </xsl:template>
    <!-- -->
    <xsl:template name="CreateAllTargetsSpecialTemplate">
    <!-- -->
    <xsl:for-each select="//root/demoTargets/demoTarget[targetName !=
    $AllTargetsWrapperConstant]">
    <xsl:element name="CallTarget">
    <xsl:attribute name="Targets">
    <xsl:value-of select="./targetName" />
    </xsl:attribute>
    </xsl:element>
    <xsl:comment> -- </xsl:comment>
    </xsl:for-each>
    <!-- -->
    </xsl:template>
    <!-- -->
    </xsl:stylesheet>



    <!-- END XSL-->


    =============================

    <!-- START BAT FILE WHICH CALLS OUTPUT FROM ABOVE-->
    <!-- Note, the output from above should be persisted in a file called
    "MSBuildXmlIssueOutput.xml" -->


    @echo off
    ECHO Demonstrate MSBuild create Own Xml Issue:
    ECHO .

    @echo on

    REM set msBuildDir=%WINDIR%\Microsoft.NET\Framework\v3.5
    set msBuildDir=%WINDIR%\Microsoft.NET\Framework\v2.0.50727

    call %msBuildDir%\msbuild /target:AllTargetsWrapper
    "MSBuildXmlIssueOutput.xml" /p:Configuration=Release
    /l:FileLogger,Microsoft.Build.Engine;logfile=MSBuildXmlIssueOutput.log

    set msBuildDir=

    <!-- END BAT FILE WHICH CALLS OUTPUT FROM ABOVE-->


    <!-- START Contents of MSBuildXmlIssueOutput.xml (after performing the
    xml/xsl transformation above)(Just to show what I got and that Martin's
    advice was spot-on -->

    <?xml version="1.0" encoding="utf-8"?>
    <Project DefaultTargets="AllTargetsWrapper"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <!-- - - -->
    <!-- - - -->
    <Target Name="AllTargetsWrapper">
    <Message Text="You just called the Target named 'AllTargetsWrapper'" />
    <!-- The above special target name will call all targets -->
    <CallTarget Targets="Target1" />
    <!-- - - -->
    <CallTarget Targets="Target2" />
    <!-- - - -->
    <CallTarget Targets="Target3" />
    <!-- - - -->
    </Target>
    <!-- - - -->
    <Target Name="Target1">
    <Message Text="You just called the Target named 'Target1'" />
    </Target>
    <!-- - - -->
    <Target Name="Target2">
    <Message Text="You just called the Target named 'Target2'" />
    </Target>
    <!-- - - -->
    <Target Name="Target3">
    <Message Text="You just called the Target named 'Target3'" />
    </Target>
    <!-- - - -->
    <!-- - - -->
    <!-- - - -->
    </Project>

    <!-- END Contents of MSBuildXmlIssueOutput.xml (after performing the xml/xsl
    transformation above) -->






    "Martin Honnen" <mahotrash@newsgroup> wrote in message
    news:O7aktfYqKHA.6064@newsgroup

    > sloan wrote:
    >

    >> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    >> version="2.0">
    >
    > You simply need to put your namespace declaration on the xsl:stylesheet
    > element, that way it applies to all literal result elements so use
    >
    > <xsl:stylesheet
    > xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    > xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
    > version="2.0">
    >
    > instead of what you have above.
    >
    > And then you can drop the namespace declaration below:
    >
    >

    >> <xsl:template match="/">
    >> <!-- -->
    >> <Project DefaultTargets="AllTargetsWrapper"
    >> xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    >
    >
    >
    >
    > --
    >
    > Martin Honnen --- MVP XML
    > http://msmvps.com/blogs/martin_honnen/


      My System SpecsSystem Spec

xml/xsl to create msbuild files........MSB4097......and an xsl workarounds(??) problems?

Similar Threads
Thread Thread Starter Forum Replies Last Post
Any workarounds for 32 bit software to run on 64 bit Vista? Jacjon Software 10 16 Sep 2009
MSBuild Project files and BuildUri Colin Desmond .NET General 0 20 Apr 2009
Backup to USB Key - any workarounds? ICT User Vista General 2 30 Sep 2008
MSBuild TargetOutputs Question. Satish .NET General 0 21 Apr 2008
Vista IE7 Last Cumulative Update F/U Workarounds etc ...winston Vista General 0 16 May 2007