提问人:John 提问时间:8/24/2023 更新时间:8/24/2023 访问量:47
在 PowerShell XmlDocument.CreateElement 中转义冒号
Escaping colon in PowerShell XmlDocument.CreateElement
问:
我正在尝试在 CreateElement 方法中转义冒号。例如,我想更改以下内容:
$node = $xmldoc.CreateElement("test:example")
给我一个看起来像这样的节点:
<test:example>
但不幸的是,我只得到这个:
<example>
有关此方法的 Microsoft 文档指出,冒号前面的任何内容都用作前缀属性,其余部分是 LocalName。前缀不会出现在节点中,因此我想采取一种解决方法,输出冒号,但不将第一部分归类为前缀。
我尝试使用baskslash来逃避它,并且通常会在其他线程上寻找不同的方法来做到这一点,但通常答案是避免首先必须逃避角色的情况。但是,我无法避免它,因为我对整个预期的XML结构没有发言权。
答:
前言:
- 以下内容不仅适用于创建元素,而且同样适用于通过
System.Xml.XmlDocument.CreateAttribute()
创建属性,但有差异。
Martin Honnen 提供了关键的提示:
如果在元素名称中使用命名空间前缀,则必须向 System.Xml.XmlDocument.CreateElement()
调用提供相应的命名空间 URI 作为第二个参数:
$node = $xmldoc.CreateElement('test:example', 'https://example.org')
或者,使用重载,在其中单独指定前缀:
$node = $xmldoc.CreateElement('test', 'example', 'https://example.org')
注意:
如果忽略了传递命名空间 URI,则前缀 (
test:
) 将被悄悄忽略并从元素名称中删除 - 即使指定的前缀已在所有者文档中定义。如果确实传递了 URI,并且前缀和 URI 都与所有者文档中的现有命名空间定义匹配,则按指定方式使用新元素/属性(没有前缀的冗余元素级定义)。
否则,将为给定的前缀创建元素级命名空间定义(例如,
<test:example xmlns:test="https://example.org" />
)
相反,如果传递命名空间 URI 但没有前缀:
和
.CreateElement(),
则指定的命名空间 URI 将作为(非前缀)新元素(例如,)的默认命名空间,除非指定的 URI 与所有者文档的默认命名空间匹配,在这种情况下,此(当时冗余的)元素级定义将被省略。
也就是说,与属性不同,见下文 - 不会应用所有者文档中为同一 URI 定义的前缀。<example xmlns="https://example.org" />
和
.CreateAttribute()
:- 如果在所有者文档中使用前缀定义了指定的命名空间 URI,则会自动应用该前缀。
- 如果不是 - 包括命名空间 URI 是所有者文档的默认命名空间 URI(!) - 将自动生成前缀(这可能是不需要的),以及前缀的元素级定义(例如,)。
<foo d0p1:example="" xmlns:d0p1="https://example1.org" />
一个独立的示例,仅关注元素:
# Create a sample document that declares a 'test' same prefix with
# a sample namespace URI.
$sampleNamespaceUri = 'https://example.org'
$doc = [xml] "<foo xmlns:test=`"$sampleNamespaceUri`"/>"
# Create the new element.
# NOTE:
# * Even though the owner document knows prefix 'test', you must still
# pass the corresponding namespace URI explcitly.
# * If the URI *differs* from the one associated with 'test' in the owner
# document, the prefix will be *redefined as part your element*, i.e.
# a 'xmlns:test="<different-URI>' attribute will be added to it.
$node = $doc.CreateElement('test:me', $sampleNamespaceUri)
# Append the element as a child node.
$null = $doc.foo.AppendChild($node)
# Print the modified document's XML text.
$doc.OuterXml
输出(修剪):
<foo xmlns:test="https://example.org">
<test:me />
</foo>
注意:如果命名空间 URI 不匹配,则会看到如下所示的内容 - 请注意,在新插入的元素级别重新定义了前缀:
<foo xmlns:test="https://example.org">
<test:me xmlns:test="https://different.example.org" />
</foo>
评论