【问题标题】:Namespaces, Schemas, Elements and Attributes in an XmlDocument in .NET.NET 中 XmlDocument 中的命名空间、架构、元素和属性
【发布时间】:2020-11-09 06:59:06
【问题描述】:

我之所以把它放在这里是因为我在尝试解决自己的问题时在 StackOverflow 上看到了很多关于 XML 的问答,并认为一旦我找到了它,我就会发布我发现的内容,以便在其他人需要时发布一些 XML 帮助,这可能会对他们有所帮助。

我的目标:创建一个包含以下 XML 声明、架构和命名空间信息的 XML 文档:

<?xml version="1.0" encoding="UTF-8"?>
<abc:abcXML xsi:schemaLocation="urn:abcXML:v12 http://www.test.com/XML/schemas/v12/abcXML_v12.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ase="urn:abcXML:v12">

我已经在 Python 中使用 minidom 做了一个快速原型,而且非常简单。不过,我需要使用 .NET 语言(C#)来完成,因为这是业务所要求的。我对 C# 非常熟悉,但我一直远离用它处理 XML,因为老实说,我对 XML 及其指南没有深入的了解。今天,我不得不面对我的恶魔。

【问题讨论】:

    标签: c# .net xml schema xml-namespaces


    【解决方案1】:

    我是这样做的:

    第一部分很简单——创建一个文档,并为根创建一个 DocumentElement(这里有一个问题,我稍后会谈到):

    XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
    XmlElement root = doc.DocumentElement;
    doc.InsertBefore(xmlDeclaration, root);
    

    下一部分似乎很简单——创建一个元素,给它一个前缀、名称和 URI,然后将它附加到文档中。我认为这会起作用,但事实并非如此(这是对 XML 的最小理解发挥作用的地方):

    XmlElement abcXML = xmlDoc.CreateElement("ase", "abcXML", "urn:abcXML:r38 http://www.w3.org/2001/XMLSchema-instance");
    XmlAttribute xmlAttr = xmlDoc.CreateAttribute("xsi:schemaLocation", "urn:abcXML:v12 http://www.test.com/XML/schemas/v12/abcXML_v12.xsd");
    abcXML.AppendChild(xmlAttr);
    xmlDoc.AppendChild(abcXML);
    

    我尝试使用doc.LoadXml()doc.CreateDocumentFragment() 并编写自己的声明。不 - 我会得到“文件意外结束”。对于那些对XmlDocumentFragment感兴趣的人:https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmldocumentfragment.innerxml?view=netcore-3.1

    这篇关于 XML 架构和命名空间的 Microsoft 文章没有直接帮助我:https://docs.microsoft.com/en-us/dotnet/standard/data/xml/including-or-importing-xml-schemas

    在阅读了更多关于 XML 的内容并浏览了 XmlDocumentXmlElementXmlAttribute 的文档后,解决方案如下:

    XmlElement abcXML = xmlDoc.CreateElement("ase", "abcXML", "urn:abcXML:r38");
    XmlAttribute xmlAttr = xmlDoc.CreateAttribute("xsi:schemaLocation", "http://www.w3.org/2001/XMLSchema-instance");
    xmlAttr.InnerXml = "urn:abcXML:v12 http://www.test.com/XML/schemas/v12/abcXML_v12.xsd";
    abcXML.Attributes.Append(xmlAttr);
    xmlDoc.AppendChild(abcXML);
    

    现在您可以像这样将元素添加到文档中:

    XmlElement header = doc.CreateElement(string.Empty, "Header", string.Empty);
    abcXML.AppendChild(header);
    

    为了保存文档,我使用了:

    xmlDoc.Save(fileLocation);
    

    我将我的输出与我的样本进行了比较,在比较了文件内容之后,我成功地匹配了它。我将输出提供给客户,他们将其上传到他们正在使用的应用程序中,但失败了:Row 1, Column 1 - Unexpected Character

    我怀疑它在编码,我是对的。使用xmlDoc.Save(fileLocation) 是正确的,但它会在第1 行第1 列生成一个带有字节顺序标记(BOM) 的UTF-8 文件。应用程序中的XML 解析函数没有预料到这一点,因此该过程失败了。为了解决这个问题,我使用了以下方法:

    Encoding enc = new UTF8Encoding(false); /* This creates a UTF-8 encoding without the BOM */
    using (System.IO.TextWriter tw = new System.IO.StreamWriter(filePath, false, enc))
    {
        xmlDoc.Save(tw);
    }
    return true;
    

    我再次生成文件,发送给客户端,它首先工作。

    我希望有人觉得这很有用。

    【讨论】:

      【解决方案2】:

      对于复杂的命名空间,只解析 xml 字符串会更简单。我喜欢使用 xml linq。您的示例 xml 是错误的。命名空间是“ase”(不是 abc)。

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Xml;
      using System.Xml.Linq;
      
      namespace ConsoleApplication1
      {
          class Program
          {
              static void Main(string[] args)
              {
                  string xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
                      "<ase:abcXML xsi:schemaLocation=\"urn:abcXML:v12 http://www.test.com/XML/schemas/v12/abcXML_v12.xsd\"" +
                         " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
                         " xmlns:ase=\"urn:abcXML:v12\">" +
                      "</ase:abcXML>";
      
                  XDocument doc = XDocument.Parse(xml);
      
                  XElement root = doc.Root;
                  XNamespace nsAse = root.GetNamespaceOfPrefix("ase");
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-12
        • 2016-12-03
        • 2010-10-27
        • 2012-08-01
        • 2013-10-16
        相关资源
        最近更新 更多