1

I have been stuck on this from a week where I am trying to append a XML node to a parent XML element. the child node and the parent node look like this :

[xml]$childxml = @"
<ClaimsProvider>
    <Bomain> hey there</Bomain>
    <Name>Login using </Name>
    <TechnicalProfiles>
        <TechnicalProfile Id="MIDC-What">
            <DisplayName> Employee</DisplayName>
            <Description>Login with your account</Description>
            <Protocol Name="OpenIdConnect" />
            <Metadata>
                <Item Key="METADATA">https://login.microsoftonline.com</Item>
                <Item Key="client_id">Mangal</Item>
                <Item Key="ValidTokenIssuerPrefixes">https://login.microsoftonline.com</Item>
            </Metadata>
            <Cryptograph>
                <Key Id="client_secret" StorageReferenceId="key" />
            </Cryptograph>
            <IncludeTechnicalProfile ReferenceId="MIDC-Shared" />
        </TechnicalProfile>
    </TechnicalProfiles>
</ClaimsProvider>
"@

And I want to add this child node to this file (filename: permissions.xml)

<TrustFrameworkPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"">
  <BasePolicy>
  </BasePolicy>
  <BuildingBlocks></BuildingBlocks>
  <ClaimsProviders>
    <ClaimsProvider>
    <Bomain> hey there 1</Bomain>
    <Name>Login using </Name>
    <TechnicalProfiles>
        <TechnicalProfile Id="MIDC-What">
            <DisplayName> Employee</DisplayName>
            <Description>Login with your account</Description>
            <Protocol Name="OpenIdConnect" />
            <Metadata>
                <Item Key="METADATA">https://login.microsoftonline.com</Item>
                <Item Key="client_id">Mangal</Item>
                <Item Key="ValidTokenIssuerPrefixes">https://login.microsoftonline.com</Item>
            </Metadata>
            <Cryptograph>
                <Key Id="client_secret" StorageReferenceId="key" />
            </Cryptograph>
            <IncludeTechnicalProfile ReferenceId="MIDC-Shared" />
        </TechnicalProfile>
    </TechnicalProfiles>
</ClaimsProvider>
    <ClaimsProvider>
    <Bomain> hey there 2</Bomain>
    <Name>Login using </Name>
    <TechnicalProfiles>
        <TechnicalProfile Id="MIDC-What">
            <DisplayName> Employee</DisplayName>
            <Description>Login with your account</Description>
            <Protocol Name="OpenIdConnect" />
            <Metadata>
                <Item Key="METADATA">https://login.microsoftonline.com</Item>
                <Item Key="client_id">Mangal</Item>
                <Item Key="ValidTokenIssuerPrefixes">https://login.microsoftonline.com</Item>
            </Metadata>
            <Cryptograph>
                <Key Id="client_secret" StorageReferenceId="key" />
            </Cryptograph>
            <IncludeTechnicalProfile ReferenceId="MIDC-Shared" />
        </TechnicalProfile>
    </TechnicalProfiles>
</ClaimsProvider>
    <ClaimsProvider>
    <Bomain> hey there 3</Bomain>
    <Name>Login using </Name>
    <TechnicalProfiles>
        <TechnicalProfile Id="MIDC-What">
            <DisplayName> Employee</DisplayName>
            <Description>Login with your account</Description>
            <Protocol Name="OpenIdConnect" />
            <Metadata>
                <Item Key="METADATA">https://login.microsoftonline.com</Item>
                <Item Key="client_id">Mangal</Item>
                <Item Key="ValidTokenIssuerPrefixes">https://login.microsoftonline.com</Item>
            </Metadata>
            <Cryptograph>
                <Key Id="client_secret" StorageReferenceId="key" />
            </Cryptograph>
            <IncludeTechnicalProfile ReferenceId="MIDC-Shared" />
        </TechnicalProfile>
    </TechnicalProfiles>
</ClaimsProvider>
  </ClaimsProviders>
</TrustFrameworkPolicy>

I am doing this right now:

  1. Saving doc in a variable
$doc = [xml](Get-Content permissions.xml)
  1. Appending the child variable to $doc xml
[Void]$doc.TrustFrameworkPolicy.ClaimsProviders.AppendChild($childxml)

I am getting the following error:

Exception calling "AppendChild" with "1" argument(s): "The specified node cannot be inserted as the valid child of this node, because the specified node is the wrong type."

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459

1 Answers1

2

You can't append an XmlNode from a different XML document. Instead you have to create a node from the document to be appended to:

$childxml = $doc.CreateDocumentFragment()
$childxml.InnerXml = @'
<ClaimsProvider>
    <Bomain> hey there</Bomain>
    <Name>Login using </Name>
    <TechnicalProfiles>
        <TechnicalProfile Id="MIDC-What">
            <DisplayName> Employee</DisplayName>
            <Description>Login with your account</Description>
            <Protocol Name="OpenIdConnect" />
            <Metadata>
                <Item Key="METADATA">https://login.microsoftonline.com</Item>
                <Item Key="client_id">Mangal</Item>
                <Item Key="ValidTokenIssuerPrefixes">https://login.microsoftonline.com</Item>
            </Metadata>
            <Cryptograph>
                <Key Id="client_secret" StorageReferenceId="key" />
            </Cryptograph>
            <IncludeTechnicalProfile ReferenceId="MIDC-Shared" />
        </TechnicalProfile>
    </TechnicalProfiles>
</ClaimsProvider>
'@

[Void]$doc.TrustFrameworkPolicy.ClaimsProviders.AppendChild($childxml)

See also: Append XML string block to existing XmlDocument

zett42
  • 25,437
  • 3
  • 35
  • 72
  • Thanks a lot @zett42 It works like a charm! – Ashwin Agarkhed Jan 18 '21 at 17:01
  • One thing, I always get the child element as` ... ` in the output. I want it to be plain vanilla `....` . Any suggessions for that? Thanks for such swift replies :-) – Ashwin Agarkhed Jan 18 '21 at 17:48
  • 1
    got it. added this `$doc.OuterXml.Replace(" xmlns=`"`"", "")` handels such stupid additions by visual code – Ashwin Agarkhed Jan 18 '21 at 17:58
  • @AshwinAgarkhed Strange, it didn't insert `xmlns=""` for me. It can happen when the target document contains a `xmlns=` attribute. In this case the clean way to fix it would be: `targetElement.AppendChild( $childxml, "InsertNameSpaceUriOfDocument")`. The function would detect that you are inserting something with same namespace as target element and omit the `xmlns=` attribute. – zett42 Jan 18 '21 at 18:15