24

我有这个代码:

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");
4

7 回答 7

31

xmlns=""添加命名空间 (un) 声明,因为您的父元素在命名空间中,而您的子元素不在。

如果您不希望添加此命名空间声明,则意味着您希望子元素与其父元素位于同一命名空间中,答案是在创建元素时将其放入此命名空间中。也就是说,更改调用CreateElement("Target", "")以指定正确的命名空间。

于 2012-11-05T09:21:20.300 回答
15

正如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);
}
于 2016-02-15T10:58:33.763 回答
13

检查这些以获取可能的解决方案:

Powershell 和 csproj

Xml 命名空间和 C# csproj

这是适用于 OP 的第二种解决方案的解决方法:

$content = [xml] $content.OuterXml.Replace(" xmlns=`"`"", "")
$content.Save($_.FullName);
于 2012-11-04T15:50:12.887 回答
1

使用 Javascript

如果您使用 JS 创建 XML 文档,并且xmlns="XXXX"在父节点上声明后在子节点上获得空白 xmlns 属性,请使用 JScreateElementNS(namespace, nodeName)而不是createElement(nodeName).

这是假设您希望您的子节点与父节点共享相同的命名空间。在以下情况下,'v1'、'v2' 等将共享 'data' 的 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);
 }

正确的结果如下所示:

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

与坏结果:

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

使用此解决方案,您还可以为您的子节点声明单独的命名空间。只需将nameSpace变量替换为不同的命名空间 uri 字符串或另一个设置变量。

于 2017-12-19T19:45:38.380 回答
1

命名空间是每个节点名称的固有部分。删除命名空间意味着需要重新创建节点。这是代码,您可以在其中创建没有 Namespace 属性的子节点。

这意味着如果您的主标记包含命名空间属性而您的子节点没有。因此,子节点将从父节点继承默认的命名空间属性。删除命名空间属性的最佳方法是

[xml]$oXMLDocument = (Get-Content "D:\myXml.xml")
# Assuming Project is the parent node with a namespace
$project = $oXMLDocument.Project
$childNode = $oXMLDocument.CreateElement("test",$project.NamespaceURI)
# (Optional) Add any attributes to the element
$childNode.SetAttribute("name", "value")
$oXMLDocument.DocumentElement.AppendChild($childNode)
# Save the document
$oXMLDocument.Save("D:\myXml2.xml")

基本上,这不会从子注释中删除命名空间属性。事实上你不能。这会将属性隐藏为默认值

如果您需要在子节点下创建子子节点,则遵循相同的样式。

于 2018-05-03T18:13:17.080 回答
0

命名空间是每个节点名称的固有部分。删除命名空间意味着需要重新创建节点。这是代码,您可以在其中创建没有 Namespace 属性的子节点。

[xml]$oXmlDocume = [xml] (Get-Content  D:\myXml.xml)
// Assuming Project is the parent node
$project = $oXMLDocument.Project
$childNode = $oXMLDocument.CreateElement("Child",$project.NamespaceURI)
$0XMLDocument.AppendChild($ChildNode)

如果您需要在子节点下创建子子节点,则遵循相同的样式。

于 2018-05-03T17:11:18.840 回答
0

我在 VBA 中构建网站地图时遇到了这个问题,但 @Neolisk 让我走上了正确的道路。这解决了我的问题:

'replace the empty attribute with nothing and load it back into the XML source
myTree.LoadXML Replace(myTree.XML, " xmlns=""""", "")

'Write that XML to a file
myTree.Save xmlFileName

感谢您的帮助,@Neolisk!

于 2022-02-18T12:38:21.100 回答