2012-04-27 15 views
6

मैं एक स्ट्रिंग के साथ एक एक्सएमएल विशेषता सेट कर रहा हूं, और पावरशेल मुझे बताता है "एक्सएमएलएनओडी गुणों को सेट करने के लिए केवल तारों का उपयोग मूल्यों के रूप में किया जा सकता है"। यहां एक साधारण उदाहरण है। सबसे पहले, मैं इस चलाएँ:PowerShell मुझे एक स्ट्रिंग कह रहा है क्यों स्ट्रिंग नहीं है? और केवल स्ट्रिंग। लम्बाई को कॉल करते समय, पहले

$xmlDoc = [xml]@" 
<root> 
    <ComponentRef Id="a" /> 
</root> 
"@ 

$newId = "b" 

$length = $newId.Length 

Write-Host ("`n`$newId is a string, see: `$newId.GetType().FullName = " + $newId.GetType().FullName + "`n") 
Write-Host ("Running `"`$xmlDoc.root.ComponentRef.Id = `$newId`"...`n") 
$xmlDoc.root.ComponentRef.Id = $newId 
Write-Host ("ComponentRef.Id is now: " + $xmlDoc.root.ComponentRef.Id) 

मेरे लिए, उत्पादन होता है:

$newId is a string, see: $newId.GetType().FullName = System.String 

Running "$xmlDoc.root.ComponentRef.Id = $newId"... 

Cannot set "Id" because only strings can be used as values to set XmlNode properties. 
At D:\Build\Tools\mass processing\Untitled4.ps1:14 char:27 
+ $xmlDoc.root.ComponentRef. <<<< Id = $newId 
    + CategoryInfo   : InvalidOperation: (:) [], RuntimeException 
    + FullyQualifiedErrorId : PropertyAssignmentException 

ComponentRef.Id is now: a 

कि त्रुटि संदेश गलत बात होनी ही थी। बराबर के दाईं ओर दिए गए मान एक स्ट्रिंग है, जैसा उपरोक्त आउटपुट में दिखाया गया है। लेकिन यह गलती हुई, इसलिए एक्सएमएल विशेषता अभी भी "ए" पढ़ती है। अब यह वीडर हो जाता है। आइए उस लाइन को टिप्पणी करें जो $ newId.length कहता है, और इसे सही तरीके से काम करता है।

इस तरह की टिप्पणी: #$length = $newId.Length। उत्पादन अब है:

$newId is a string, see: $newId.GetType().FullName = System.String 

Running "$xmlDoc.root.ComponentRef.Id = $newId"... 

ComponentRef.Id is now: b 

मैं एक फिक्स के लिए पूछ नहीं कर रहा हूँ, क्योंकि मैं कैसे इस समस्या के पिछले असाइनमेंट ऑपरेटर के दाईं ओर करने के लिए [स्ट्रिंग] कास्टिंग द्वारा काम करने के लिए पता है। मैं क्या जानना चाहता हूं:

क्या कोई समझा सकता है कि क्यों $ newId.Length (एक गेटर!) को कॉल करना PowerShell को $ new सोचने का कारण बन सकता है Id अब स्ट्रिंग नहीं है?

धन्यवाद!

+0

समस्या लगता है कि PowerShell ऑब्जेक्ट रूट से अनुकूलित कैसे होते हैं .NET ऑब्जेक्ट्स (उदाहरण के लिए, सी # में आप नहीं कर सकते ' टी xmlDoc.root पर कॉल करें - रूट एक ऐसी संपत्ति है जो पीएस जोड़ रही है)। यह पीएस और आपके द्वारा सामना की जाने वाली किसी भी .NET ऑब्जेक्ट्स के लिए पारदर्शी होना चाहिए, इसलिए मुझे यकीन नहीं है कि यह क्यों उड़ रहा है। उदाहरण के लिए $ xmlDoc.root.ComponentRef.SetAttribute ("आईडी", $ newId) ठीक काम करता है। बहुत अजीब ... –

+0

यह ऐसा कुछ होना चाहिए। यह निश्चित रूप से अजीब है कि कॉलिंग लम्बाई इसे ट्रिगर करेगी। मुझे लगता है कि यह एक PowerShell बग है। हो सकता है कि जहां तक ​​उत्तर जायेगा, हम देखेंगे;) मुझे यकीन नहीं है कि क्या PowerShell टीम आम जनता से बग रिपोर्ट लेती है या नहीं। – Vimes

+1

जॉनबी वे बग रिपोर्ट लेते हैं - एक लाइव आईडी के साथ connect.microsoft.com/powershell में लॉगिन करें और रेब्रो के साथ बग लॉग करें। – x0n

उत्तर

6

यह वी 2 विस्तारित प्रकार प्रणाली में एक दुर्भाग्यपूर्ण बग है जहां psobject रैपर आधार के आसपास बनाया जा सकता है .NET प्रकार। यह तब हो सकता है जब आप किसी ऑब्जेक्ट में सदस्यों को जोड़ते हैं या जब आप उस प्रॉपर्टी तक पहुंचते हैं जो मौजूद नहीं है। यह तब भी हो सकता है जब आप किसी ऑब्जेक्ट IIRC पर psobject प्रॉपर्टी एक्सेस करते हैं। $newId.psobject। जब आप पावरशेल के भीतर रहते हैं तो यह आमतौर पर किसी भी समस्या का कारण नहीं बनता है।

अद्यतन: यह .NET को कॉल करने में कोई समस्या नहीं है। कुछ त्वरित .NET परीक्षण कोड से पता चलता है कि यह एक संपत्ति सेटर के लिए एक अनचाहे वस्तु हो जाता है। Trace-Command के साथ इस को देखने के बाद यह PowerShell के XmlNodeAdapater में एक बग हो गया लगता है:

DEBUG: ETS Information: 0 : Method  Enter PSObject..ctor():object = System.Management.Automation.RuntimeException: 
Cannot set "Id" because only strings can be used as values to set XmlNode properties. ---> 
System.Management.Automation.SetValueException: Cannot set "Id" because only strings can be used as values to set 
XmlNode properties. 
    at System.Management.Automation.XmlNodeAdapter.PropertySet(PSProperty property, Object setValue, Boolean 
convertIfPossible) 
    at System.Management.Automation.Adapter.BasePropertySet(PSProperty property, Object setValue, Boolean convert) 
    at System.Management.Automation.PSProperty.SetAdaptedValue(Object setValue, Boolean shouldConvert) 
    at System.Management.Automation.PSProperty.set_Value(Object value) 
    at System.Management.Automation.PropertyReferenceNode.SetValue(PSObject obj, Object property, Object value, 
ExecutionContext context) 
    --- End of inner exception stack trace --- 
    at System.Management.Automation.PropertyReferenceNode.SetValue(PSObject obj, Object property, Object value, 
ExecutionContext context) 
    at System.Management.Automation.AssignablePropertyReference.SetValue(Object value, ExecutionContext context) 
    at System.Management.Automation.AssignmentStatementNode.Execute(Array input, Pipe outputPipe, ExecutionContext 
context) 
    at System.Management.Automation.StatementListNode.ExecuteStatement(ParseTreeNode statement, Array input, Pipe 
outputPipe, ArrayList& resultList, ExecutionContext context) 

एक तरीका यह सुनिश्चित करने के लिए आप हमेशा base .NET ऑब्जेक्ट प्राप्त है:

$xmlDoc.root.ComponentRef.Id = $newId.psobject.baseobject 

अच्छी खबर यह मुद्दा यह है कि है वी 3 में तय किया गया है उदाहरण:

PS> $xmlDoc = [xml]@" 
<root> 
    <ComponentRef Id="a" /> 
</root> 
"@ 

PS> $newId = "b" 

PS> $newId.Length 
1 

PS> $newId.psobject.typenames 
System.String 
System.Object 

PS> $xmlDoc.root.ComponentRef.Id = $newId 

PS> $xmlDoc | format-xml # From PowerShell Community Extensions 
<root> 
    <ComponentRef Id="b" /> 
</root> 
+1

समझ में आता है कि एक्सएमएल एडाप्टर समस्या पैदा कर रहा है। यह समझाएगा कि .NET विधि SetAttribute पर वापस क्यों आ रहा है: $ xmlDoc.root.ComponentRef.SetAttribute ("आईडी", $ newId) –

+0

मुझे 5.0 (विंडोज़ 10) में एक ही समस्या है।ऐसा लगता है कि यह "फीचर" फिर से पॉप अप हो रहा है ... –

+0

ओपी की स्क्रिप्ट 5.0 बिल्ड 5.0.10130.0 पर मेरे लिए काम करती है। आप किस 5.0 का निर्माण कर रहे हैं? –

संबंधित मुद्दे