我在反序列化带有真正定义的“未定义”命名空间前缀的 XML 时遇到问题。
我们用 C# 发布了一个内部 Web 服务,它为各种客户提供服务。新客户端的 IDE 坚持为其 XML 输出中的每个元素声明 xsi:type,并且他们无法关闭此“功能”。
他们生成的 XML 消息是这样的,其中“命名空间”是正确的命名空间。
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<myOperation xsi:type="ns1:namespace" xmlns="namespace" xmlns:ns1="namespace">
<inputString xsi:type="xsd:string">ABCDEF</inputString>
<books xsi:type="ns1:booksType">
<bookID xsi:type="xsd:string">ABC123</bookID>
<bookID xsi:type="xsd:string">DEF456</bookID>
</books>
<!-- ... snip... -->
</myOperation>
</soapenv:Body>
<books>
基本上是一个字符串数组。
服务方法接受为 XmlNode,但 XmlSerializer 会抛出“prefix 'ns1' not defined”错误。(它是在父节点中定义的,但显然这还不够好。)我有一个类似的问题,使用 wsdl.exe 为我生成类和反序列化输入。
使用 XmlNamespaceManager 来指定前缀似乎并不正确——类似于幻数,而且我无法预测给定消费者将声明哪个前缀。有没有办法在不剥离属性的情况下处理这个问题(books.Attributes.RemoveAll)?这也感觉不是特别优雅。
我发现 books.OuterXML 不包含任何有关“ns1”的信息,除非我破解入站元素以使用该前缀 (),所以我可以看到它为什么会抱怨,但我还不明白为什么“ns1”是'不能从上面之前的定义中识别出来。
非常感谢有人可以提供的任何帮助,或者至少是教育。
编辑:如果我更改<books>
为使用前缀,即<ns1:books xsi:type="ns1:booksType">
. 无论我是否定义了 xmlns,这都有效。这可能与这个答案一致,但我仍然看不到如何在服务代码中声明前缀。
@Chris,当然。希望我能在“吝啬封闭源代码”和“对那些愿意提供帮助的人有用”之间取得平衡。这里的“books”是服务方法参数中接收到的 XmlNode。(不要脱离话题,但也会虚心接受建议以改进它;我还是个新手。)
XmlSerializer xmlSerializer = new XmlSerializer(typeof(booksType));
StringReader xmlDataReader = new StringReader(books.OuterXml);
books = (booksType)xmlSerializer.Deserialize(xmlDataReader);
这个类几乎是这样的:
[Serializable()]
[XmlRoot("books", Namespace = "namespace")]
[XmlTypeAttribute(TypeName = "booksType", Namespace = "namespace")]
public class booksType
{
[XmlElement(ElementName = "bookID")]
public string[] bookIDs { get; set; }
}