3

I want to create element OutputPath with text. This is what I want:

  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
    <OutputPath>Text</OutputPath>
  </PropertyGroup>

and this is what I get:

  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
    <OutputPath xmlns="">Text</OutputPath>
  </PropertyGroup>

Everything is good but when I create element something keeps adding xmlns="" to it.

And then I get error: error MSB4097: The element beneath element may not have a custom XML namespace.

    // Load the Project (.innoproj or .nsisproj file)
    xmlDoc := nil;
    currentConfigurationNode := nil;
    xmlDoc := CreateOleObject('Microsoft.XMLDOM') as IXMLDOMDocument2;
    xmlDoc.async := False;
    //xmlDoc.setProperty('SelectionNamespaces', 'xmlns="http://schemas.microsoft.com/developer/msbuild/2003"'); << this line does nothing
    xmlDoc.load(projPath);
    if xmlDoc.parseError.errorCode <> 0 then
    begin
      xmlDoc := nil;
      currentConfigurationNode := nil;
      raise Exception.Create('Cannot not load Project file! Details: ' + xmlDoc.parseError.reason);
    end;

    // Find appropriate element and get it's value
    { <?xml><Project><PropertyGroup Condition=" '$(Configuration)' == 'XXX' "> }
    propertyGroup := xmlDoc.selectNodes('/Project/PropertyGroup');
    for I := 0 to propertyGroup.length - 1 do
    begin
      node := propertyGroup[I];
      if (node.attributes.length > 0) then
      begin
        Temp := String(node.attributes.getNamedItem('Condition').Text);
        if(Temp.Contains('$(Configuration)') and Temp.Contains(projConfiguration)) then
        begin
          // Do all operations on this node
          currentConfigurationNode := propertyGroup[I];
          break;
        end;
      end;
    end;

    Result := True;
  except
    on Exception do
      Result := False;
  end;

Creating (new) node:

  // This is correct Node for selected Configuration
  node := currentConfigurationNode.selectSingleNode(PPED^.XmlTag);
  if(node <> nil) then
    if(PPED^.Value <> '') then
    begin
      elementNode := currentConfigurationNode.appendChild(xmlDoc.createElement(PPED^.XmlTag));
      elementNode.text := PutSymbol(PPED^.Strip, PPED^.Value); << Something adds xmls="" to this element
    end;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Slappy
  • 5,250
  • 1
  • 23
  • 29
  • Slappy, what delphi version are you using? More recent delphi versions include OmniXML support and does not expose this kind of problem. – whosrdaddy Jun 20 '15 at 17:55

1 Answers1

2

Pass in the root element's namespace when creating the element:

xmlDoc.createElement(PPED^.XmlTag, rootElementNamespace);

I don't know what the root element's namespace is, but presumably you do. The document has the information too so I expect you can write:

XmlDoc.DocumentElement.NamespaceURI

for the root element namespace.

I guess that your question should be considered a dupe of this: How to prevent blank xmlns attributes in output from .NET's XmlDocument? But I didn't close it as such because the mods in the Delphi tag tend to dislike closing against questions from non-Delphi tags.

Community
  • 1
  • 1
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • This is correct, using namespace helped, thanks! It looks like this is the same problem in C# and Delphi - IXMLDOMDocument2 object is just wrapper about some COM object - which is probably the same for .NET. – Slappy Jun 21 '15 at 07:14
  • Indeed. The same libraries are in use here. – David Heffernan Jun 21 '15 at 07:20