如何在 XML 属性中保存换行符?
Posted
技术标签:
【中文标题】如何在 XML 属性中保存换行符?【英文标题】:How to save newlines in XML attribute? 【发布时间】:2011-01-01 12:59:36 【问题描述】:我需要在某些 XML 属性中保存包含换行符的内容,而不是文本。 应该选择该方法,以便我能够在 XSLT 1.0/ESXLT/XSLT 2.0 中对其进行解码
最好的编码方法是什么?
请建议/提供一些想法。
【问题讨论】:
Are line breaks in XML attribute values valid?的可能重复 为类似问题做了一个例子:***.com/a/29782321/611007 相关:***.com/questions/260436 - 相关:***.com/questions/449627 - 相关:***.com/questions/1289524 【参考方案1】:您可以使用实体

来表示XML 属性中的换行符。 
可用于表示回车。 Windows 样式的 CRLF 可以表示为 

。
这是合法的 XML 语法。详情请见XML spec。
【讨论】:
它是一个有效的 XML 字符吗?? 我想我必须使用一些编码而不是实体,因为 getAttribute 不适用于包含换行符的字符串。你有很多想法吗?实体会解决getAttribute问题吗? @Chathuranga Chandrasekara:是的。它是有效的 XML。我更新了我的答案,包括一个指向提到这些符号的 XML 规范的链接。 @Tommy:你使用什么编程语言/API?你说的这个getAttribute()
方法是什么?
@Asaph:javascript。客户端:javascript。服务器端:php (xslt 1.0/esxlt)、tomcat (xslt 2.0 saxon8)。【参考方案2】:
在兼容的 DOM API 中,您无需执行任何操作。只需将实际的换行符保存到属性中,API 就会自行正确编码(参见Canonical XML spec, section 5.2)。
如果您自己进行编码(即在保存属性值之前将\n
替换为

),API 将再次对您的输入进行编码,从而在XML 文件中生成

.
底线是,字符串值被逐字保存。你把你放进去的东西拿出来,不需要干涉。
但是…有些实现不兼容。例如,他们将在属性值中编码&
字符,但忘记换行符或制表符。这会使您处于亏损状态,因为您不能简单地事先用

替换换行符。
这些实现将保存未编码的换行符,如下所示:
<xml attribute="line 1
line 2" />
在解析这样的文档时,属性中的文字换行符被规范化为一个空格(同样,根据规范) - 因此它们会丢失。
在这些实现中,不可能在属性中保存(并保留!)换行符。
【讨论】:
我遇到的事情:XML 使用 Unix 风格的换行符 (LF)。因此,如果您想存储 Windows 样式的换行符 (CR+LF),您需要在读取属性后转换换行符,或者以某种方式转义换行符。来源:w3schools.com/xml/xml_syntax.asp @Joe:您从哪里获取 XML 使用 Unix 样式换行符的信息?据我所知,the spec 并没有限制。 @Joe:对不起,我不给 w3schools 很多可信度。如果它在规范中,那将是另一回事。 @Tomalak:嗯,好吧,那很公平。我什至在查看之前就看到了效果。这里来自规范:w3.org/TR/xml/#sec-line-ends -- 引用“为了简化应用程序的任务,XML 处理器必须表现得好像它在解析之前对输入的外部解析实体(包括文档实体)中的所有换行符进行了规范化,通过将两个字符序列 #xD #xA 和任何后面没有 #xA 的 #xD 转换为单个 #xA 字符。" 使用the NewLineHandling property(通过将其设置为Entitize)可以使.NET Framework 的XmlWriter 行为正确且(合理)合理。不幸的是,在 Firefox 中实现的 XML DOM 中不可能保留换行符 - a 2002 bug - 而 Chrome 的实现是正确的。【参考方案3】:粗略的回答可以是:
XmlDocument xDoc = new XmlDocument();
xDoc.Load(@"Agenda.xml");
//make stuff with the xml
//make attributes value = "\r\n" (you need both expressions to make a new line)
string a = xDoc.InnerXml.Replace("
", "\r").Replace("
", "\n").Replace("><",">\r \n<");
StreamWriter sDoc = new StreamWriter(@"Agenda.xml");
sDoc.Write(a);
sDoc.Flush();
sDoc.Dispose();
如你所见,这只是一个字符串
【讨论】:
【参考方案4】:在某些情况下有所帮助的略有不同的方法-
占位符和查找和替换。
在解析之前,您可以简单地使用您自己的自定义换行标记/占位符,然后在第二半情况下,只需将字符串替换为任何有效的换行符,无论是 \n 还是 要么 或 #&10;或 \u2028 或任何各种换行符。在最初在数据中设置您自己的占位符后,查找并替换它们。
当像 jQuery $.parseXML() 这样的解析器去除未编码的换行符时,这很有用。例如,您可以使用 LBREAK 作为换行符,在原始文本中插入它,然后在解析为 XML 对象后替换它。 String.replaceAll() 是一个有用的原型。
带有 jquery 和 replaceAll 原型的粗略代码概念(尚未测试此代码,但它会显示概念):
function onXMLHandleLineBreaks(_result)
var lineBreakCharacterThatGetsLost = ' ';
var lineBreakCharacterThatGetsLost = '
';
var rawXMLText = _result; // hold as text only until line breaks are ready
rawXMLText = String(rawXMLText).replaceAll(lineBreakCharacterThatGetsLost, 'mylinebreakmarker'); // placemark the linebreaks with a regex find and replace proto
var xmlObj = $.parseXML(rawXML); // to xml obj
$(xmlObj).html( String(xmlObj.html()).replaceAll('mylinebreakmarker'), lineBreakCharacterThatWorks ); // add back in line breaks
console.log('xml with linebreaks that work: ' + xmlObj);
当然,您可以根据您的数据情况调整有效或无效的换行符,您可以将其放入循环中以获取一组无效的换行符并遍历它们以做一整套换行符。
【讨论】:
以上是关于如何在 XML 属性中保存换行符?的主要内容,如果未能解决你的问题,请参考以下文章