Friday, November 13, 2009

MSBuild + XMLUpdate + XPath + Namespaces

Today I came across an issue trying to use an XMLUpdate statement against the web.config in our team deployment build, and while the Googling did end up helping me resolve the issue, it didn't turn up any direct results that really showed/explained what I needed to do. So what would Brian Boitano do? Well, besides using his magical fire breath to save a maiden, he'd probably decide to dig up the rotting corpse of his blog and fill the void himself. So here we are!


Anyways, check out the relevant chunk of my config file (sensitive info obfuscated, of course):

xml version="1.0"?>

<configuration>

...

<openaccess xmlns="http://www.telerik.com/OpenAccess">

<references>

<reference assemblyname="OurAssembly.Name" configrequired="True" />

</references>

<connections>

<connection id="OurDatabase">

<databasename>OurDB</databasename>

<servername>.\SQLEXPRESS</servername>

<integratedSecurity>True</integratedSecurity>

<backendconfigurationname>mssqlConfiguration</backendconfigurationname>

<connectionParams></connectionParams>

</connection>

</connections>

<backendconfigurations>

<backendconfiguration id="mssqlConfiguration" backend="mssql">

<mappingname>mssqlMapping</mappingname>

<logging.logEventsToTrace>False</logging.logEventsToTrace>

<logging.logEvents>verbose</logging.logEvents>

<lockTimeout>5000</lockTimeout>

<logging.logEventsToSysOut>False</logging.logEventsToSysOut>

</backendconfiguration>

</backendconfigurations>

</openaccess>

...


</configuration>

As you can see, we're using the Telerik OpenAccess ORM tools. My goal was to insert some values into the connectionParams node specific to our deployed application scenario, so I originally had a statement in the team build proj file that looked like this:


<XmlUpdate XmlFileName="%(WebConfig.FullPath)"

XPath="//configuration/openaccess/connections/connection[@id='OurDatabase']/@connectionParams"

Value="AttachDbFileName=$(DropLocation)\$(LabelName)\$(Configuration)\_PublishedWebsites\$(WebProjectName)\OurDB.mdf" />

Unfortunately, it didn’t work. After some digging I discovered that the xmlns attribute on the openaccess node messes with XPath, and that I could use a Namespace attribute to help solve that problem, but nothing really showed how exactly to do it. I used a little trial and error and came up with the solution as seen here:


<XmlUpdate XmlFileName="%(WebConfig.FullPath)"

Prefix="n"

Namespace="http://www.telerik.com/OpenAccess"

XPath="//configuration/n:openaccess/n:connections/n:connection[@id='OurDatabase']/n:connectionParams"

Value="AttachDbFileName=$(DropLocation)\$(LabelName)\$(Configuration)\_PublishedWebsites\$(WebProjectName)\OurDB.mdf" />


So as a way of explanation, we define the namespace we're hunting for and assign it a prefix. Then, in the XPath, we use the prefix for any node that falls within that namespace, but not for the nodes before it takes effect (such as configuration).


All of this info is out there on the web in pieces, and I'm sure smarter folks than I can put it together quickly and move on, but hopefully this post will help the other goobers like me who would otherwise take an hour or two to put all the pieces of the puzzle together.


Faithfully yours,

Code Baboon

31 comments:

Mike said...

What was that about Brian Boitano voiding himself on the maiden?

JohnCello said...

Thanks. This was a big help. I used this to help update an NHibernate (for version 2.1) connection string in config files:



<ItemGroup>

<ConfigVar Include="NHConnStr">
<XPath>//configuration/nh:hibernate-configuration/nh:session-factory/nh:property[@name='connection.connection_string']</XPath>
<Namespace>urn:nhibernate-configuration-2.2</Namespace>
<Prefix>nh</Prefix>
</ConfigVar>


<ConfigVar Include="ConnStr">
<XPath>configuration/connectionStrings/add[@name='DBConnStr']/@connectionString</XPath>
<Namespace></Namespace>
<Prefix></Prefix>
</ConfigVar>

<ConfigVar Include="PathToDir">
<XPath>configuration/appSettings/add[@key='PathToDir']/@value</XPath>
<Namespace></Namespace>
<Prefix></Prefix>
</ConfigVar>

</ItemGroup>


<Target Name="RunConfig" Outputs="%(ConfigVar.Identity)">

<PropertyGroup>
<RunConfig_CurrValue></RunConfig_CurrValue>
</PropertyGroup>

<XmlRead Prefix="%(ConfigVar.Prefix)" Namespace="%(ConfigVar.Namespace)" XPath="%(ConfigVar.XPath)" XmlFileName="$(InputConfig)">
<Output TaskParameter="Value" PropertyName="RunConfig_CurrValue"/>
</XmlRead>


<XmlUpdate
Prefix="%(ConfigVar.Prefix)"
Namespace="%(ConfigVar.Namespace)"
XPath="%(ConfigVar.XPath)"
XmlFileName="$(DropConfig)"
Value="$(RunConfig_CurrValue)" />

</Target>

韋于倫成 said...

好問才能博學。........................................

Be224nWann1 said...

78論壇 A片,成人影片分享 080視訊聊天室 666成人 視訊交友網 xvideo免費影片 視訊美女ws888 6k聊天室辣妹視訊 A片-免費視訊 視訊美女mybank sex888影音視訊聊天室 影音情人趣味 85cc免費影片 視訊激麻館 禁地論壇成人 情色視訊 成人影片情色網 bt成人論壇 18成人avooo 玩美女人試看片 hilive tv視訊妹 免費聊天firework av999免費影片 avdvd無碼影片成人情色 一葉晴貼影片av127 520聊天室 一夜情視訊聊天室 視訊聊天室交友 免費視訊辣妹avdvd一夜情 1元視訊 網愛聊天 250av女優免費影片 免費影音視訊fm358 sex女優王國情色 嘟嘟情人色網 dvd 台灣18網 視訊交友雙贏論壇 色a金激麻館 性愛故事性愛文學 凹凸情欲網 成人視訊happylife 視訊聊天交友mm358 免費視訊辣妹sex女優王國 情色香港論壇 亞洲情色貼圖區 日本 a 片自拍偷拍網站情色小說 免費avi影片下載 台灣情色視訊網 17358 視訊聊天室 日本a片免費下載 情色影片免費觀賞you tube影片下載

HaroldM22 said...

your wife is very charming!............................................................

慶天 said...

金銀愈加磨鍊,愈加光亮,人生愈加考驗,生命愈加光輝。 ............................................................

walsha said...

Necessity is the mother of invention.............................................................

juliancu said...

噴泉的高度,不會超過它的源頭。一個人的事業也是如此,它的成就絕不會超過自己的信念。..................................................

雅馨 said...

If the quantity is not a lot, I will hand carry..................................................

博行 said...

very nice blog~~......................................................................

林怡洋 said...

一定要保持最佳狀況呦,加油!!!期待你發表的新文章!.................................................................                           

江婷 said...

上班好累哦,看看部落格轉換心情~~~先謝謝啦!!.................................................................                           

佳蓉佳蓉 said...

一個人的價值,應該看他貢獻了什麼,而不是他取得了什麼............................................................

宥妃宥妃 said...

安一估~你也安一估哦~............................................................

與發 said...

這麼好的部落格,以後看不到怎麼辦啊!!..................................................................

JasonBirk佳琪 said...

一個人就像一個分數,他的實際才能是分子,他對自己的評價是分母。分母越大,則分數的價值越小。..................................................

姿柯瑩柯dgdd憶曾g智曾 said...

有夢最美啦~~加油!元氣滿點!............................................................

陳芳 said...

臨淵羨魚,不如退而結網。............................................................

家榮家榮 said...

困難的不在於新概念,而在於逃避舊有的概念。............................................................

錢靜怡錢靜怡錢靜怡 said...

thank you so much~~ SUPPORT!!............................................................

胡維倫 said...

道歉是人類一定必要的禮節..................................................

家唐銘 said...

好文!值得一推~~加油哦!............................................................

筱佳恩婷 said...

Man proposes, God disposes..................................................................

文岳仲君 said...

馬丁路德:「即使知道明天世界即將毀滅,我仍願在今天種下一棵小樹。」............................................................

王辛江淑萍康 said...

Since it is the early worm that gets eaten by the bird, sleep late...................................................................

偉曹琬 said...

人因夢想而偉大,要堅持自己的理想哦!............................................................

冠陳儒 said...

要保持更新呦,加油!!!期待你的新文章!!!............................................................

惠邱邱邱邱雯 said...

Necessity is the mother of invention..................................................................

翊翊翊翊張瑜翊翊翊 said...

我是天山,等待一輪明月。......................................................................

群育航學 said...

你不能決定生命的長度,但你可以控制它的寬度..................................................................

志涛 said...

知識可以傳授,智慧卻不行。每個人必須成為他自己。............................................................