【问题标题】:Split the String, If it exceeds the specified length拆分字符串,如果超过指定长度
【发布时间】:2013-04-18 13:58:33
【问题描述】:

我正在使用字符串生成器生成 XML 格式文件。该文件将如下所示:-

  StringBuilder strBldr = new StringBuilder();
  strBldr.AppendLine("<Root>");
  strBldr.AppendLine("<ProductDetails>");
  strBldr.AppendLine("<PId>" + lblproductid.Text + "</PId>");
  strBldr.AppendLine("<PDesc>" + strtxtProductDesc + "</PDesc>");
  strBldr.AppendLine("</ProductDetails>");
  strBldr.AppendLine("</Root>");

这是在 for 循环中,因此它可能包含许多产品详细信息。 现在我需要拆分这个字符串,如果它超过了限制长度假设 100。 到目前为止,这很容易。我可以使用以下方法拆分它:-

 public static IEnumerable<string> SplitByLength(this string str, int maxLength)
 {
        for (int index = 0; index < str.Length; index += maxLength)
        {
            yield return str.Substring(index, Math.Min(maxLength, str.Length - index));
        }
  }

但问题是,如果它发现长度大于 100,此方法只是简单地拆分字符串。但我需要确定它是否尝试从 xml 节点的中间拆分,然后它应该找到上面的 @ 987654324@ 节点并从那里拆分。 我应该在代码中添加什么来实现这一点?

【问题讨论】:

  • 这听起来很老套,这里的总体目标是什么?您是否尝试返回 XML 节点的集合?因为有更好的方法来做到这一点......
  • 如果单个节点的内容超过100个字符会怎样?
  • 永远不要将 xml 构建为字符串。使用XDocument。不要从 xml 文档中随机删除内容。修复任何消费者无法处理超过 100 个字符的问题。
  • @DGibbs :感谢您的回复。实际上在这里我想将该字符串(使用 xml 格式)存储在数据库表中,所以如果它超过了限制长度(假设为 5000),并且如果该长度介于任何子节点之间,那么它应该从“”标签和应该插入下一行。
  • @RajeshBiswas 您是否对ProductDetails 的列施加了字符限制,例如varchar(5000)?如果是这样,您可以在前端将用户输入限制为特定数量的字符(减去 XML),以防止这种情况发生,从而解决您的问题。 varchar max 最多可以存储 8000 个字节/字符...

标签: c# asp.net xml linq


【解决方案1】:

如果lblproductid.Text 包含,例如&amp;&lt;&gt;,会怎样?

因此,我将使用真正的 xml 解析器,而不是手动形成它。

var xElem = new XElement("Root",
                    new XElement("ProductDetails",
                        new XElement("PId", lblproductid.Text),
                        new XElement("PDesc",strtxtProductDesc)));

var xml = xElem.ToString();

输出将是:

<Root>
  <ProductDetails>
    <PId>aaa</PId>
    <PDesc>aaa</PDesc>
  </ProductDetails>
</Root>

PS:你可以循环ProductDetails并计算总长度。

【讨论】:

    【解决方案2】:

    您绝对应该使用XDocument 而不是string 来构造和查询XML 数据。

    您可以在 XDocument 类上创建一个扩展方法,该方法将按长度拆分:

    public static class XDocumentExtensions
    {
        public static IEnumerable<string> SplitByLength(this XDocument source, string elementName, int maxLength)
        {
            if (source == null)
                throw new ArgumentNullException("source");
            if (string.IsNullOrEmpty(elementName))
                throw new ArgumentException("elementName cannot be null or empty.", "elementName");
            if (maxLength <= 0)
                throw new ArgumentException("maxLength has to be greater than 0.", "maxLength");
    
            return SplitByLengthImpl(source, elementName, maxLength);
        }
    
        private static IEnumerable<string> SplitByLengthImpl(XDocument source, string elementName, int maxLength)
        {
            var builder = new StringBuilder();
    
            foreach (var element in source.Root.Elements(elementName))
            {
                var currentElementString = element.ToString();
                if (builder.Length + currentElementString.Length > maxLength)
                {
                    if (builder.Length > 0)
                    {
                        yield return builder.ToString();
                        builder.Clear();
                    }
                    else
                    {
                        throw new ArgumentException(
                            "source document contains element with length greater than maxLength", "source");
                    }
                }
    
                builder.AppendLine(currentElementString);
            }
            if (builder.Length > 0)
                yield return builder.ToString();
        }
    }
    

    然后像这样使用它:

    var parts = doc.SplitByLength("ProductDetails", 200).ToList();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-03
      • 1970-01-01
      • 1970-01-01
      • 2022-11-23
      • 1970-01-01
      相关资源
      最近更新 更多