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;
1
  • Slappy, what delphi version are you using? More recent delphi versions include OmniXML support and does not expose this kind of problem. Commented Jun 20, 2015 at 17:55

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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.
Indeed. The same libraries are in use here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.