【问题标题】:Xml Serialization to XmlAttribute: namespace prefix lost when Element in same namespaceXml 序列化到 XmlAttribute:当元素在同一命名空间中时,命名空间前缀丢失
【发布时间】:2013-07-30 16:08:58
【问题描述】:

我需要生成一个 xml 文档,其中所有元素和属性都以(相同的)命名空间为前缀(我知道这并不理想,但不幸的是需要与 InfoPath 进行互操作)。使用 .NET XmlSerializer,使用正确的命名空间和前缀进行初始化,生成带前缀的 xml 通常没有问题:

xmlSerializer = new XmlSerializer(typeof(T));
xmlNamespaces = new XmlSerializerNamespaces();
xmlNamespaces.Add("foo", "www.namespace.com");

...

[XmlRoot(Namespace = "www.namespace.com")]
public class label
{
    [XmlAttribute(Namespace = "www.namespace.com")]
    public string id { get; set; }

    [XmlElement(Namespace = "www.namespace.com")]
    public string text { get; set; }  
}  

这会生成 xml

<foo:label id="0" xmlns:foo="www.namespace.com">
    <foo:text>content</foo:text>
</foo:label>

问题是这样的:前缀适用于所有内容,但同一命名空间中的“id”属性除外。

我认为这可能是 W3C 规定的行为,并且声明为属于前缀元素的属性将继承该前缀。但是,似乎没有关联命名空间/前缀的属性不会像这样 - 请参阅 XML namespaces and attributeshere,其中指出:

“一个属性永远不会继承其父元素的命名空间。因此,一个属性只有在具有适当的命名空间前缀时才位于命名空间中”

在这种情况下,序列化程序不应该生成一个前缀来显示该属性在该命名空间中吗?或者这不正确?

提前致谢!

更多信息:进一步调查(参见下面 SamuelNeff 的回答)已确定无前缀属性不会继承其包含元素的命名空间。这是否意味着 XmlSerializer 正在产生不合规格的属性?有没有办法强制它添加前缀?如果在 XmlAttribute 属性中添加了不同的命名空间 uri,它添加一个前缀。

【问题讨论】:

    标签: c# xml serialization prefix


    【解决方案1】:

    OOPS:我对规范的解释是错误的。这个不正确的响应被标记为答案,所以我不能删除它。对不起。

    没有前缀的属性与其包含的元素在同一个命名空间中。如果属性具有与其元素不同的命名空间,则只需对属性应用前缀。

    默认命名空间声明不直接应用于属性名称;无前缀属性的解释由它们出现的元素决定。

    http://www.w3.org/TR/2009/REC-xml-names-20091208/#defaulting

    【讨论】:

    • 啊,太好了,谢谢@SamuelNeff。我认为序列化程序如此公然破坏命名空间会令人惊讶。所以这 - stackoverflow.com/a/43226/1603434 - 大概是不正确的吧?
    • @Tryptamine42,看起来我对规范的解释是错误的,而您指出的问题是正确的。不带前缀的属性获取无前缀作用域的默认命名空间,而不是带前缀元素的命名空间。我根据另一个问题进行了一些测试,jelovirt 是正确的。
    • 感谢您回复这个问题 - 我昨晚对此感到困惑,因为我运行了一些类似的测试,其中无前缀属性的 xpath 与它们不匹配。规范在这一点上似乎相当模棱两可(“解释无前缀属性由元素决定”表示属性 inherit 命名空间是有意义的)所以我认为我们的困惑是可以理解的!有趣的是,这可能意味着 XmlSerializer 正在产生不合规格的属性...
    【解决方案2】:

    尝试使用Prefix 属性?

    XmlAttribute Prefix on MSDN

    这是一个相当奇怪的问题,手动设置PrefixNamespaceURI 也可能容易出错。您确定属性上的命名空间甚至是必要的吗?虽然它可能不规范,但您正在使用的客户端或服务器应该跳过该属性的包含元素,如果它位于您的 foo 命名空间中,对吗?在什么时候它会关心你的属性有什么命名空间。

    【讨论】:

    • 感谢@welegan,明智的建议,这确实是一个奇怪的问题。希望我能尽快放弃 InfoPath 互操作,这样对元素和属性的双重前缀的需求就会消失。直接修改 DOM 中的属性 Prefix 属性是备用计划,但如果可能的话,我想避免它,因为理想情况下我希望所有 xml 生成都由序列化程序完成(有趣的是,反序列化时它并不关心属性是否是否有前缀 - 我确定这不可能)。
    猜你喜欢
    • 2012-11-19
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-02
    • 1970-01-01
    相关资源
    最近更新 更多