Hi All. I have xml file:
<?xml version="1.0" encoding="utf-8" ?> <variables> <!--My first variable--> <acsrv>%AppData%\MyCompanyName\MySoftName</acsrv> <!--My second variable--> <wproj>%AppData%\MyCompanyName\MySoftName</wproj> </variables>
I need for each 'variables' item create new environment variable (in user profile). I can't get value for xml item. My code:
# Current directory $curDir = $MyInvocation.MyCommand.Definition | split-path -parent # xml file full name $xmlFile = "$curDir\variables.xml" # Reed variables from xml file $xmldata = [xml](Get-Content $xmlFile) # Create or reset variables $xmldata.variables foreach {[Environment]::SetEnvironmentVariable($_.Name, $_.Value, "User")}
1. What should I write instead of "$ _.Value"? 2. How from sampling to eliminate objects of comments?
I read it chapter, but haven't found the answer.
Sorry for my EnglishRegards
Hi,
The easiest way is to re-structure your XML file.
<?xml version="1.0" encoding="utf-8" ?> <variables> <!--My first variable--> <name>acsrv</name> <value>%AppData%\MyCompanyName\MySoftName</value> <!--My second variable--> <name>wproj</name> <value>%AppData%\MyCompanyName\MySoftName</value> </variables>
Felipe: The easiest way is to re-structure your XML file.
I think that this bad problem resolution.
Well and I think that is a bad XML file. But I'm here to help and not to criticize.
Anyway...
Another way to do it:
$xmldata = [xml](Get-Content $xmlFile)$properties = $xmldata | Get-Member -MemberType property | select -ExpandProperty name foreach($_ in $xml){[Environment]::SetEnvironmentVariable($_.($properties[1]), $_.($properties[2]), "user")}
$xmldata = [xml](Get-Content $xmlFile)$properties = $xmldata | Get-Member -MemberType property | select -ExpandProperty name
foreach($_ in $xml){[Environment]::SetEnvironmentVariable($_.($properties[1]), $_.($properties[2]), "user")}
Felipe:Well and I think that is a bad XML file.
I would like to manage more laconic variant xml. At me many such files also will alter all of them not rationally. By means of LINQ to XML I easily work with any xml. I wouldn't like to start to edit xml only because PowerShell something can't make. :(((
Thanks for the code, but it don't work. Even if I will replace in a cycle ' foreach ' a name of unknown variable ' $xml ' on ' $xmldata ' all the same, as a result, I receive an error. The variable '$properties' as values contains ' variables ' and ' xml ', and it not those values which need to be selected.
Regards
Sorry I missed something. Try this:
$xmldata = [xml](Get-Content $xmlFile)$properties = $xmldata.variables | Get-Member -MemberType property | select -ExpandProperty name for($i=1;$i -lt $properties.count; $i++){ if($properties[$i] -match "#comment"){$i++} else{ [Environment]::SetEnvironmentVariable($_.($properties[$i]), $_.($properties[$i+1]), "user")}}
$xmldata = [xml](Get-Content $xmlFile)$properties = $xmldata.variables | Get-Member -MemberType property | select -ExpandProperty name
for($i=1;$i -lt $properties.count; $i++){
if($properties[$i] -match "#comment"){$i++}
else{
[Environment]::SetEnvironmentVariable($_.($properties[$i]), $_.($properties[$i+1]), "user")}}
If you are consistent with your XML files this should work.
No, it not work too.
# Current directory $curDir = $MyInvocation.MyCommand.Definition | split-path -parent # xml file full name $xmlFile = "$curDir\variables.xml" # Reed variables from xml file $xmldata = [xml](Get-Content $xmlFile) $properties = $xmldata.variables | Get-Member -MemberType property | select -ExpandProperty name for($i=1;$i -lt $properties.count; $i++){ if($properties[$i] -match "#comment"){$i++} else{ # Check values: $_.($properties[$i]) + " = " + $_.($properties[$i+1]) # [Environment]::SetEnvironmentVariable($_.($properties[$i]), $_.($properties[$i+1]), "user") } }
I get it:
= =
I get it: = =
That suggests that the two Propertiies values are both blank!
Let me play some more...
>That suggests that the two Propertiies values are both blank!
It is incorrect. In the first message of this subject I have shown contents of the xml a file.
I successfully derive the data by means of XPath and XSLT:
Xml source file:
1: <?xml version="1.0" encoding="utf-8" ?> 2: <?xml-stylesheet type="text/xsl" href="xpath2.xsl"?> 3: <variables> 4: <!--My first variable--> 5: <acsrv>%AppData%\MyCompanyName\MySoftName</acsrv> 6: <!--My second variable--> 7: <wproj>%AppData%\MyCompanyName\MySoftName</wproj> 8: </variables>
1: <?xml version="1.0" encoding="utf-8" ?>
2: <?xml-stylesheet type="text/xsl" href="xpath2.xsl"?>
3: <variables>
4: <!--My first variable-->
5: <acsrv>%AppData%\MyCompanyName\MySoftName</acsrv>
6: <!--My second variable-->
7: <wproj>%AppData%\MyCompanyName\MySoftName</wproj>
8: </variables>
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output encoding="UTF-8" method="text"/> <xsl:template match="/"> <xsl:for-each select="/variables/child::*"> <xsl:value-of select="name()"/> <xsl:text> = </xsl:text> <xsl:value-of select="."/> <xsl:text>
</xsl:text> </xsl:for-each> </xsl:template> </xsl:stylesheet>
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" method="text"/>
<xsl:template match="/">
<xsl:for-each select="/variables/child::*">
<xsl:value-of select="name()"/>
<xsl:text> = </xsl:text>
<xsl:value-of select="."/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Result (if xml file open in browser):
acsrv = %AppData%\MyCompanyName\MySoftName wproj = %AppData%\MyCompanyName\MySoftName
In PowerShell too it is used XPath, but at me it is impossible to pick up analog "." (point).
OK - I've got two basic comments about this.
First, I can see what's happening. Your use of Get-Member transforms the XMLdata into simple strings, so what follows does indeed break. I think you want to just work with the XML Data.
Second, you expose some interesting aspects of XML handling in .NET!
So let's star with the $xmldata. On my system, I see this:
Psh[Cookham8:C:\foo\xml]>$xmldata.variables#comment acsrv wproj -------- ----- ----- {My first variable, My second variable} %AppData%\MyCompanyName\MySoftName %AppData%\MyCompanyName\MySoftName
Note that the two comments are somehow munged under the comment element.
A better way to do this, imho, would be by restructuring your XML as follows:
<?xml version="1.0" encoding="utf-8" ?> <variables> <variable> <!--My first variable--> <name>acsrv</name> <value>%AppData%\MyCompanyName\MySoftName</value> </variable> <variable> <!--My second variable--> <name>wproj</name> <value>%AppData%\MyCompanyName\MySoftName</value> </variable> </variables>
Doing this means you can do this:
$xmlFile = ".\variables2.xml"$y = #comment# Read variables from xml file$xmldata = [xml](Get-Content $xmlFile)Foreach ($var in $vars) {$v = $var.($var.GetEnumerator().name[0])" {0,-20} name: {1,15} is being set to: {2}" -f $v,$var.name, $var.value[Environment]::SetEnvironmentVariable($var.name,$var.value, "user")}
Now I'm sure there are better ways to do this, but it's Friday night and I'm wacked out!
In general though, while I am sure we could do it your way, the more verbose style of XML noted in this post is more in keeping with what I'd expect.
I hope this helps.
BTW: where areu based?
Bush: >That suggests that the two Propertiies values are both blank! It is incorrect. In the first message of this subject I have shown contents of the xml a file.
In the cited code, the two property values were blank - I can duplicate your issue.
I'm not a wizzard at XML and I certainly do not pretend to know all there is to know about XML. But what I would have expected to see in an XML file would be more like this:
<?xml version="1.0" encoding="utf-8" ?> <variables> <variable> <comment>My first variable</comment> <name>acsrv</name> <value>%AppData%\MyCompanyName\MySoftName</value> </variable> <variable> <comment>My second variable</comment> <name>wproj</name> <value>%AppData%\MyCompanyName\MySoftName</value> </variable> </variables>
This is more typical of the XML I deal with where there's a formal schema and you don't have random tag name. IMHO, the 'comment' is more a business comment and therefore is part of the data being persisted in XML rather than an XML comment about the XML itself.
Hope this helps.
Thomas
Thomas Lee:A better way to do this, imho, would be by restructuring your XML as follows
It is possible to change xml a file that it was easier to work with it. But I nevertheless would like to find the decision and for the given variant.
Today I was very tired. I will study your answer tomorrow in more details.
Thomas Lee:BTW: where areu based?
I am from Saint Petersburg (Russia).
Sorry for my English
I'm just trying to help. I could probably wade into the xml and work out how to do it, but IMHO, the XML itself is not great XML. IMHO, you want XML to schematatized and the approach you are trying to use does not lend itself to being such).
There is at least a workable answer on the table. I hope this helps.
Welcome to from, in case i did not say so before - and your English is far better than my Russian!
Thanks :)