【问题标题】:', hexadecimal value 0x0B, is an invalid character. Line 78839, position 103.'',十六进制值 0x0B,是无效字符。线 78839,位置 103。
【发布时间】:2021-08-07 00:35:36
【问题描述】:

我得到了标题中指定的错误。¨注意我已经按照其他线程中的建议使用了 XmlConvert.IsXmlChar 但是我仍然得到错误。

XDocument GetXDocument(string fileName, CloudBlobDirectory folder)
{
    CloudBlockBlob blob = folder.GetBlockBlobReference(fileName);

    using (var memoryStream = new MemoryStream())
    {   
        blob.DownloadToStream(memoryStream);
        memoryStream.Seek(0, SeekOrigin.Begin);

        StreamReader sr = new StreamReader(memoryStream, Encoding.UTF8);
        var xml = sr.ReadToEnd();
        var validXmlChars = xml.Where(ch => XmlConvert.IsXmlChar(ch)).ToArray();
        xml = new string(validXmlChars);

        return XDocument.Parse(xml);
    }
}

这是失败的那一行:

<Property Name="Printkode" Type="String" Access="ReadWrite" Value="%% d2m*DOKSTART|&#xB;d2m*OVERSKRIFT:&quot;xx&quot;|&#xB;d2m*CPR:&quot;xxx&quot;" />

【问题讨论】:

  • .Net 中的 XML 阅读器无法读取无效的 XML。在解析之前将文本修复为有效的 XML 是您唯一的选择。请注意,您需要修复实际的无效字符(如“\u000b”)以及在帖子“”中显示后转义。
  • 单个字符&amp;#xB; 都是有效的,但它们一起代表一个无效的垂直制表符。
  • Value 属性代表什么?您应该考虑使用不同的编码。
  • 我有任何内置的东西可以删除无效部分。编码与顶部xml中指定的相同。
  • 你怎么知道所有垂直的无效标签?

标签: c# xml linq-to-xml


【解决方案1】:

由于还没有答案,我想提供一种方法。我的方法的主要关键是使用 CDATA,您只需将段落标记为不需要反序列化的字符数据。我根据您的 sn-p 构建了一个简单的 XML:

<?xml version="1.0" encoding="utf-8" ?> 
   <Property Name="Printkode" Type="String" Access="ReadWrite">
      <Value>
          <![CDATA[%% d2m*DOKSTART|&#xB;d2m*OVERSKRIFT: 
          &quot;xx&quot;|&#xB;d2m*CPR:&quot;xxx&quot;]]>
      </Value>
   </Property>

现在可以像在您的代码中一样将此文件反序列化为 XDocument:

public void DeserializeXML()
    {
        using var file = File.Open(@"C:\XMLFile1.xml", FileMode.Open);
        StreamReader sr = new StreamReader(file, Encoding.UTF8);
        var xml = sr.ReadToEnd();
        var result =XDocument.Parse(xml);
    }

以下结果:

这样您就可以进入您的 XDocument。然而,挑战将是在需要的地方实现所有 CDATA 部分。这完全取决于您的情况和您给定的 XML。希望对大家有所帮助!

【讨论】:

  • 我无法控制 xml 的生成。它是由 Microsoft 产品生产的。
  • 尽管如此,应该可以先将其作为字符串读取,识别所有具有令人不安的十六进制值的部分,将它们放入 CDATA 部分,然后将其反序列化为 XDocument。
  • 但问题是我无法通过它们,因为由于此错误,无法通过一半的文档。我开始考虑使用正则表达式来删除所有属性节点。
  • 好吧,我实际上以为你想找到一种方法来进一步传递它,它就是信息。如果属性节点与您完全无关,并且在任何地方都没有说明,那么肯定有一种正则表达式方式。
【解决方案2】:

您可以通过解码转义字符来双重测试特殊转义字符:

var xs = String.Concat(s.Where(ch => XmlConvert.IsXmlChar(ch)));
xs = xs.Replace(new Regex(@"&.+?;"), m => XmlConvert.IsXmlChar(WebUtility.HtmlDecode(m.Value)[0]) ? m.Value : "");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-17
    • 2016-11-14
    • 2016-03-30
    • 1970-01-01
    • 1970-01-01
    • 2011-10-07
    • 2015-06-23
    • 2016-08-05
    相关资源
    最近更新 更多