如何在.Net中创建此XML?

时间:2012-03-09 11:07:09

标签: .net xml xml-serialization xmldocument xmlwriter

我需要将对象序列化为.Net中的以下XML。

可能最简单的方法是实现IXMLSerializable,因为我需要对最终结果进行控制....我需要做什么才能在以下模式中输出:

<ns2:ProcessRepairOrder languageCode="de-DE" releaseID="1.0" systemEnvironmentCode="PROD" versionID="1.0">
    <ns2:ApplicationArea>
       <ns2:Sender>
          <ns2:CreatorNameCode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns3:TextType">SomeVendor</ns2:CreatorNameCode>
          <ns2:SenderNameCode name="Dave"/>
       <ns2:Sender>
    </ns2:ApplicationArea>
</ns2:ProcessRepairOrder>

更具体地说,它是没有命名空间的前缀,而xsi:type我无法进入XML。

完整版看起来像这样:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
  <S:Body>
    <ns1:PutMessage xmlns:ns1="http://www.starstandards.org/webservices/2009/transport" xmlns:ns2="http://www.starstandard.org/STAR/5" xmlns:ns3="http://www.openapplications.org/oagis/9">
      <ns1:payload>
        <ns1:content>
          <ns2:ProcessRepairOrder languageCode="de-DE" releaseID="1.0" systemEnvironmentCode="PROD" versionID="1.0">
          ...many more XML elements
      </ns2:ProcessRepairOrder>
    </ns1:PutMessage>
  </S:Body>
</S:Envelope>

1 个答案:

答案 0 :(得分:2)

你能使用.NET 3.5吗?如果是这样,LINQ-to-XML可能更容易使用。以下是我测试过的一些代码,它们将在您的问题中生成完整的XML输出:

XNamespace ns2 = "some-uri";
XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance";

XElement root = new XElement("Root",
    // Define ns2 namespace on Root element
    new XAttribute(XNamespace.Xmlns + "ns2", ns2.NamespaceName),
    new XElement(ns2 + "ProcessRepairOrder",
        // Attributes of ProcessRepairOrder
        new XAttribute("languageCode", "de-DE"),
        new XAttribute("releaseID", "1.0"),
        new XAttribute("systemEnvironmentCode", "PROD"),
        new XAttribute("versionID", "1.0"),
        // Child elements of ProcessRepairOrder
        new XElement(ns2 + "ApplicationArea",
            new XElement(ns2 + "Sender",
                new XElement(ns2 + "CreatorNameCode",
                    // Attributes of CreatorNameCode and define xsi namespace
                    new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName),
                    new XAttribute(xsi + "type", "ns3:TextType"),
                    // Value of CreatorNameCode,
                    "SomeVendor"
                ),
                new XElement(ns2 + "SenderNameCode",
                    // Attributes of SenderNameCode
                    new XAttribute("name", "Dave")
                )
            )
        )
    )
);

您可以查看this MSDN page以了解如何使用LINQ-to-XML创建XML tress,this link说明如何将XML命名空间应用于它们。

<强>编辑:

从下面的评论开始,似乎你想要一个不太标准的方法,因为你不能拥有我在上面定义的根元素,但LINQ-to-XML似乎需要它才能创建一个有效的定义了正确名称空间的XML结构。如果你想使用这种方法,那么有一种解决方法,但它需要更多地摆弄输出。

使用我上面编写的代码然后执行root.Elements().First().ToString()将产生这个序列化的XML:

<ns2:ProcessRepairOrder languageCode="de-DE" releaseID="1.0" systemEnvironmentCode="PROD" versionID="1.0" xmlns:ns2="some-uri">
  <ns2:ApplicationArea>
    <ns2:Sender>
      <ns2:CreatorNameCode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns3:TextType">SomeVendor</ns2:CreatorNameCode>
      <ns2:SenderNameCode name="Dave" />
    </ns2:Sender>
  </ns2:ApplicationArea>
</ns2:ProcessRepairOrder>

几乎可以注意到LINQ-to-XML已在xmlns:ns2上插入了ProcessRepairOrder命名空间,因为要在整个层次结构中使用ns2元素,需要在某处定义它。但是现在您已经使用字符串格式,您可以轻松地使用String.Replace()删除它,并最终得到您所需的内容。

我不会说它是一个优雅的解决方案,但它适用于您生成XML的非标准方法。