Как сохранить новые строки в атрибуте XML? - PullRequest
56 голосов
/ 05 января 2010

Мне нужно сохранить контент, содержащий символы новой строки в некоторых атрибутах XML, а не текст. Метод должен быть выбран так, чтобы я мог декодировать его в XSLT 1.0 / ESXLT / XSLT 2.0

Какой метод кодирования лучший?

Пожалуйста, предложите / дайте несколько идей.

Ответы [ 4 ]

70 голосов
/ 06 января 2010

В совместимом API DOM вам ничего не нужно делать. Просто сохраните фактические символы новой строки в атрибуте, API самостоятельно закодирует их правильно (см. Спецификация канонического XML, раздел 5.2 ).

Если вы выполняете свою собственную кодировку (т.е. заменяете \n на 
 перед сохранением значения атрибута), API снова закодирует ваш ввод , что приведет к 
 в файле XML.

Суть в том, что строковое значение сохраняется дословно. Вы получаете то, что вы положили, не нужно вмешиваться.

Однако … некоторые реализации не совместимы. Например, они будут кодировать & символов в значениях атрибутов, но забудут о символах новой строки или вкладках. Это ставит вас в проигрышную позицию, поскольку вы не можете просто заменить символы новой строки на 
 заранее.

Эти реализации будут сохранять символы новой строки в незашифрованном виде, например:

<xml attribute="line 1
line 2" />

При анализе такого документа буквальные символы новой строки в атрибутах нормализуются в один пробел (опять же, в соответствии со спецификацией) - и, таким образом, они теряются.

Сохранение (и сохранение!) Новых строк в атрибутах невозможно в этих реализациях.

41 голосов
/ 05 января 2010

Вы можете использовать объект &#10; для представления новой строки в атрибуте XML. &#13; может использоваться для обозначения возврата каретки. CRLF в стиле Windows может быть представлен как &#13;&#10;.

Это допустимый синтаксис XML. Подробнее см. XML spec .

0 голосов
/ 18 января 2019

Немного другой подход, который был полезен в некоторых ситуациях -

Заполнители и поиск и замена.

Перед синтаксическим анализом вы можете просто использовать свой собственный маркер / заполнитель переноса строки, затем во 2-й половине ситуации просто замените строку на любой эффективный символ перевода строки, будь то \ n или или же или # & 10; или \ u2028 или любой из различных символов разрыва строки там. Найдите и замените их обратно после первоначальной установки собственного заполнителя в данных.

Это полезно, когда парсеры, такие как jQuery $ .parseXML (), удаляют незашифрованные разрывы строк. Например, вы могли бы использовать {LBREAK} в качестве символа разрыва строки, вставить его во время необработанного текста и заменить его позже после анализа в объекте XML. String.replaceAll () - полезный прототип.

Итак, грубая концепция кода с jquery и прототипом replaceAll (этот код не тестировался, но он покажет концепцию):

function onXMLHandleLineBreaks(_result){
    var lineBreakCharacterThatGetsLost = '&#10;';
    var lineBreakCharacterThatGetsLost = '&#xD;';
    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);
}

И, конечно, вы можете настроить символы разрыва строки, которые работают или не работают, в вашей ситуации с данными, и вы можете поместить это в цикл для набора символов разрыва строки, которые не работают, и выполнить итерацию по ним, чтобы сделать целый набор символов разрыва строки.

0 голосов
/ 03 ноября 2011

Грубый ответ может быть:

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("&#xD;", "\r").Replace("&#xA;", "\n").Replace("><",">\r    \n<");
StreamWriter sDoc = new StreamWriter(@"Agenda.xml");
sDoc.Write(a);
sDoc.Flush();
sDoc.Dispose();

Это, как вы видите, просто строка

...