【问题标题】:XML writer not including end tagXML 编写器不包括结束标记
【发布时间】:2013-10-30 17:21:47
【问题描述】:

谁能告诉我为什么我的 XML 编写器在他们这样吃的时候没有写出结束标签:/ >

我正在做的是读取一个 xml 文件,然后将其写入一个新文件,如果找到某些元素,我会执行一些代码,然后用新的元素覆盖这些元素。整个目的是复制第一个文档中几乎所有的 xml,除非它找到需要执行不同代码的特定元素,这些代码将依次输出作者添加的新元素。到目前为止,它几乎可以正常工作,除了结束标签。

这是它应该是什么样子的 sn-p(用星号标注的不同示例):

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <ProjectGuid>{57900E99-A405-49F4-83B2-0254117D041B}</ProjectGuid>
    <Keyword>Win32Proj</Keyword>
    <RootNamespace>libprojex</RootNamespace>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" **/>**
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <CharacterSet>MultiByte</CharacterSet>
    **<PlatformToolset>v110</PlatformToolset>**
  </PropertyGroup>

这是我的输出:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <ProjectGuid>{57900E99-A405-49F4-83B2-0254117D041B}</ProjectGuid>
    <Keyword>Win32Proj</Keyword>
    <RootNamespace>libprojex</RootNamespace>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props">
    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
      <ConfigurationType>DynamicLibrary</ConfigurationType>
      <UseDebugLibraries>true</UseDebugLibraries>
      <CharacterSet>MultiByte</CharacterSet>
    </PropertyGroup>

这些只是简短的摘录。他们在整个文档中继续。如果您注意到以 /&gt; 结尾的行,它不会正确地将它们添加到编写器。输出中也缺少此行 &lt;PlatformToolset&gt;v110&lt;/PlatformToolset&gt;

我已经包含了一些代码来展示我是如何实现这一点的:

string vcName = Path.GetFileName(textBox1.Text);
string vcProj = Path.Combine(baseDir, vcName);

using (XmlReader reader = XmlReader.Create(textBox1.Text))
{
    XmlWriterSettings settings = new XmlWriterSettings();
    settings.ConformanceLevel = ConformanceLevel.Auto;
    settings.Indent = true;
    settings.CloseOutput = false;
    string nameSpace = "http://schemas.microsoft.com/developer/msbuild/2003";
    using (XmlWriter writer = XmlWriter.Create(vcProj, settings))
    {

        while (reader.Read())
        {
            switch (reader.NodeType)
            {
                case XmlNodeType.Element:

                   if (reader.Name == "ClInclude")
                    {
                        //execute code here- omitted for example
                        writer.WriteStartElement(reader.Name, nameSpace);
                        writer.WriteAttributeString("Include", "include/" + filename);
                        writer.WriteEndElement();

                    }
                    else if (reader.Name == "ClCompile" && reader.HasAttributes)
                    {
                        //execute code here- omitted for example
                        writer.WriteStartElement(reader.Name, nameSpace);
                        writer.WriteAttributeString("Include", "src/" + filename);
                        writer.WriteEndElement();

                    } 
                   else
                    {
                        writer.WriteStartElement(reader.Name, nameSpace);
                        writer.WriteAttributes(reader, true);
                    }

                    break;

                case XmlNodeType.Text:
                    writer.WriteString(reader.Value);
                    break;
                case XmlNodeType.XmlDeclaration:
                case XmlNodeType.ProcessingInstruction:
                    writer.WriteProcessingInstruction(reader.Name, reader.Value);
                    break;
                case XmlNodeType.Comment:
                    writer.WriteComment(reader.Value);
                    break;
                case XmlNodeType.Attribute:
                    writer.WriteAttributes(reader, true);
                    break;
                case XmlNodeType.EntityReference:
                    writer.WriteEntityRef(reader.Value);
                    break;
               case XmlNodeType.EndElement:
                    writer.WriteFullEndElement();
                    break;

                }
        }

    }

谁能告诉我为什么我会遇到这些问题,是它以某种方式忽略了无效的 XML 吗?

【问题讨论】:

  • 除了你所面临的实际问题,你有什么特别的理由使用XmlReader吗? LINQ to XML 使用起来很多简单,除非您有大量文档要避免读入内存,否则它会让您的生活更轻松。
  • 我没有理由,我只是开始这样做并继续这样做。虽然它已被证明是少数。我正在尝试使用 Linq to XML,但我似乎无法遍历所有“ClInclude”元素。可以举个例子吗?
  • 只要foreach (var element in doc.Descendants(ns + "ClInclude"))ns 是一个合适的XNamespace)就可以了。如果您有问题,我建议您专门提出一个新问题,包括您尝试过的内容以及您正在尝试做的事情。

标签: c# .net xml visual-studio-2010


【解决方案1】:

我怀疑你的这部分代码:

else
{
  writer.WriteStartElement(reader.Name, nameSpace);
  writer.WriteAttributes(reader, true);
}

尝试添加 writer.WriteEndElement();就像你对其他 if 块所做的那样。

【讨论】:

    【解决方案2】:

    看来 Import 既是 Element 又是 EndElement。但是在 Element 中创建之后,你就简单地突破而不关闭。

    附:使用 LinqToXML 和 XElement 会容易得多...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多