Удалите ненужный (пустой) атрибут xmlns, добавленный appendChild

У меня есть этот код:

function setupProject($projectFile) {
  [xml]$root = Get-Content $projectFile;

  $project = $root.Project;

  $beforeBuild = $root.CreateElement("Target", "");
  $beforeBuild.SetAttribute("name", "BeforeBuild");
  $beforeBuild.RemoveAttribute("xmlns");
  $project.AppendChild($beforeBuild);

  $root.Save($projectFile);
}

Он должен добавить новый <Target name="BeforeBuild" /> в документ XML.

Но он также добавляет пустой атрибут xmlns="", который я не хочу. (Это на самом деле Visual Studio, которая не любит этот атрибут!)

<Target name="BeforeBuild" xmlns="" />

Я уже пробовал этот код:

$beforeBuild.RemoveAttribute("xmlns");
$project.AppendChild($beforeBuild);
$beforeBuild.RemoveAttribute("xmlns");

Ответ 1

Проверьте их на возможные варианты:

Powershell и csproj

пространство имен Xml и С# csproj

Ниже приведено обходное решение второго решения, которое работало для OP:

$content = [xml] $content.OuterXml.Replace(" xmlns=`"`"", "")
$content.Save($_.FullName);

Ответ 2

Объявление xmlns = "namespace (un) добавлено, потому что ваш родительский элемент находится в пространстве имен, а ваш дочерний элемент - нет. Если вы не хотите, чтобы это объявление пространства имен было добавлено, подразумевается, что вы хотите, чтобы дочерний элемент находился в том же пространстве имен, что и его родительский элемент, и ответ заключается в том, чтобы поместить его в это пространство имен во время создания элемента. То есть, измените вызов CreateElement (" Target "," "), чтобы указать правильное пространство имен.

Ответ 3

Как ответил Michael Kay, лучший способ удалить это нежелательное пространство имен - это создать новый дочерний элемент в том же пространстве имен, что и его родительский:

function setupProject($projectFile) {
  [xml]$root = Get-Content $projectFile;

  $project = $root.Project;

  //UPDATE THIS LINE $beforeBuild = $root.CreateElement("Target", "");
  $beforeBuild = $root.CreateElement("Target", $project.NamespaceURI);
  $beforeBuild.SetAttribute("name", "BeforeBuild");
  $beforeBuild.RemoveAttribute("xmlns");
  $project.AppendChild($beforeBuild);

  $root.Save($projectFile);
}

Ответ 4

Использование Javascript

Если вы используете JS для создания документа XML и получаете чистые атрибуты xmlns на дочерних узлах после объявления xmlns="XXXX" в родительском node, используйте JS createElementNS(namespace, nodeName) вместо createElement(nodeName).

Предполагается, что ваши дочерние узлы будут использовать одно и то же пространство имен как родительский. В следующем случае "v1", "v2" и т.д. Будут совместно использовать NS "данных"

Он будет выглядеть примерно так:

let data = someArray;
let nameSpace = 'XXX';
let doc = "<?xml version='1.0' encoding='utf-8' ?><data xmlns='XXXX'></data>";
let parser = new DOMParser();
let xml = parser.parseFromString(doc, "text/xml");

for (let i = 0; i < data.length; i++) {
    let node = xml.createElementNS(nameSpace , "v" + (i + 1));
    $(node).text(data[i]);
    let elements = xml.getElementsByTagName("data");
    elements[0].appendChild(node);
 }

Результат CORRECT будет выглядеть так:

<?xml version='1.0' encoding='utf-8' ?>
<data xmlns='XXXX'>
    <v1></v1>
    <v2></v2>
</data>

Результат против BAD:

<?xml version='1.0' encoding='utf-8' ?>
<data xmlns='XXXX'>
    <v1 xmlns=""></v1>
    <v2 xmlns=""></v2>
</data>

С помощью этого решения вы также можете объявить отдельные пространства имен для дочерних узлов. Просто замените переменную nameSpace другой строкой uri пространства имен или другой переменной набора.