20

I'm a beginner in web development, and I'm trying to insert line breaks in my XML file. This is what my XML looks like:

<musicpage>
   <song>
      <title>Song Title</title>
      <lyric>Lyrics</lyric>
   </song>

    <song>
      <title>Song Title</title>
      <lyric>Lyrics</lyric>
   </song>

    <song>
      <title>Song Title</title>
      <lyric>Lyrics</lyric>
   </song>

    <song>
      <title>Song Title</title>
      <lyric>Lyrics</lyric>
   </song>
</musicpage>

I want to have line breaks in between the sentences for the lyrics. I tried everything from /n, and other codes similar to it, PHP parsing, etc., and nothing works! Have been googling online for hours and can't seem to find the answer. I'm using the XML to insert data to an HTML page using Javascript.

Does anyone know how to solve this problem?

And this is the JS code I used to insert the XML data to the HTML page:

<script type="text/javascript">

    if (window.XMLHttpRequest) {
    xhttp=new XMLHttpRequest();
} else {
    xhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xhttp.open("GET","xml/musicpage_lyrics.xml",false);
xhttp.send("");
xmlDoc=xhttp.responseXML;

var x=xmlDoc.getElementsByTagName("songs");
for (i=0;i<x.length;i++) {
    document.write("<p class='msg_head'>");
    document.write(x[i].getElementsByTagName("title")[0].childNodes[0].nodeValue);
    document.write("</p><p class='msg_body'>");
    document.write(x[i].getElementsByTagName("lyric")[0].childNodes[0].nodeValue);
    document.write("</p>");
}
</script>
ew89
  • 203
  • 1
  • 2
  • 6
  • Please post some code showing how you are using the XML. – John Saunders Jun 06 '10 at 23:24
  • 1
    Can you clarify one thing? Are you having trouble building the XML file (if you open it up in a dumb text editor, do you see what you expect to see?) or are you having trouble rendering the text in the browser. My suspicion is that the problem is that browsers render ANY white space (spaces, tabs, line-breaks, etc.) as a single space, so the problem isn't the XML, it's the text. You need to add `
    ` (note the trailing slash) to have it render in the browser or you need to write it to a `
    ` block.
    – Andrew Jun 06 '10 at 23:32
  • The XML is pretty much what I posted on the top of the page, and I've added the Javascript code that I used to insert the XML data to the HTML page (just in case it's needed). – ew89 Jun 06 '10 at 23:32
  • I'm having trouble rendering the text in the browser, not building the XML file. And I want the line breaks to be editable through the XML file itself and not the HTML file, so the
    option might not be usable. But thanks, I'll explore through the different options given to me.
    – ew89 Jun 06 '10 at 23:44
  • 1
    @ew89: The XML you posted doesn't appear to have any newlines within the tags at all... what are you expecting? – Thanatos Jun 07 '10 at 00:27
  • That's just a sample of what my XML looks like, in the actual file there are multiple lyric lines; I simplified it to make it easier to understand. But anyways, someone provided me with a working CDATA solution. – ew89 Jun 07 '10 at 00:45
  • 2
    @ew98: But by simplifying it, you've removed how you've been inserting newlines into your XML, turning it into just a generic piece of XML. The newlines that you're inserting are crucial to the problem at hand - it would be useful to see what you're doing, so we could validate it as correct or incorrect. Otherwise, it's just XML, and I know what XML looks like. – Thanatos Jun 07 '10 at 00:59
  • Ok, I'll keep that in mind for future reference. – ew89 Jun 07 '10 at 01:22

9 Answers9

28

@icktoofay was close with the CData

<myxml>
    <record>
        <![CDATA[
        Line 1 <br />
        Line 2 <br />
        Line 3 <br />
        ]]>
    </record>
</myxml>
Chase Florell
  • 42,985
  • 56
  • 169
  • 364
22

In XML a line break is a normal character. You can do this:

<xml>
  <text>some text
with
three lines</text>
</xml>

and the contents of <text> will be

some text
with
three lines

If this does not work for you, you are doing something wrong. Special "workarounds" like encoding the line break are unnecessary. Stuff like \n won't work, on the other hand, because XML has no escape sequences*.


* Note that &#xA; is the character entity that represents a line break in serialized XML. "XML has no escape sequences" means the situation when you interact with a DOM document, setting node values through the DOM API.

This is where neither &#xA; nor things like \n will work, but an actual newline character will. How this character ends up in the serialized document (i.e. "file") is up to the API and should not concern you.


Since you seem to wonder where your line breaks go in HTML: Take a look into your source code, there they are. HTML ignores line breaks in source code. Use <br> tags to force line breaks on screen.

Here is a JavaScript function that inserts <br> into a multi-line string:

function nl2br(s) { return s.split(/\r?\n/).join("<br>"); }

Alternatively you can force line breaks at new line characters with CSS:

div.lines {
    white-space: pre-line;
}
Tomalak
  • 306,836
  • 62
  • 485
  • 598
  • nope, doesn't work..but I'll look into it more. Thanks! – ew89 Jun 06 '10 at 23:23
  • 4
    @ew89: Of course it works. You are just trying to solve the wrong problem. – Tomalak Jun 06 '10 at 23:26
  • 2
    This is the real answer. If everything is working well, a simple newline should do it. Some parsers have a flag to selectively ignore whitespace, so that you can use it to indent your XML file, but I doubt that's your problem. (which is, IMHO, an abuse of the format.) Whitespace in XML is *significant*, including the tabs/spaces you use for indentation. – Thanatos Jun 07 '10 at 00:25
7

just use &lt;br&gt; at the end of your lines.

7

At the end of your lines, simply add the following special character: &#xD;

That special character defines the carriage-return character.

KushalP
  • 10,172
  • 6
  • 30
  • 27
  • I tried that too, but the code just simply doesn't show up in the HTML page, both as a line break and as literal typing; but the rest of the XML data loads perfectly. – ew89 Jun 06 '10 at 23:16
  • 3
    @ew89: Line breaks in source code do not cause linebreaks in rendered HTML. For HTML you want `
    ` tags.
    – Tomalak Jun 06 '10 at 23:18
  • 1
    @Scorchin: You could use a simple literal linebreak. There is no need to encode it except in attribute values. – Tomalak Jun 06 '10 at 23:22
  • Is there a way to enable the linebreaks in the XML file/source code to render in the HTML page? It's because I'm doing it for a client, and she doesn't have any HTML knowledge. – ew89 Jun 06 '10 at 23:25
  • And I tried using the literal linebreak, but everything just ended up showing in one line. – ew89 Jun 06 '10 at 23:26
  • @ew89: Please *read* the comments you get. – Tomalak Jun 06 '10 at 23:27
  • I tried them, but I can't seem to get them to work. Maybe it's just my lack of knowledge in the field. Thanks anyway!:) – ew89 Jun 06 '10 at 23:34
4

In the XML: use literal line-breaks, nothing else needed there.

The newlines will be preserved for Javascript to read them [1]. Note that any indentation-spaces and preceding or trailing line-breaks are preserved too (the reason you weren't seeing them is that HTML/CSS collapses whitespace into single space-characters by default).

Then the easiest way is: In the HTML: do nothing, just use CSS to preserve the line-breaks

.msg_body {
    white-space: pre-line;
}

But this also preserves your extra lines from the XML document, and doesn't work in IE 6 or 7 [2].

So clean up the whitespace yourself; this is one way to do it (linebreaks for clarity - Javascript is happy with or without them [3]) [4]

[get lyric...].nodeValue
    .replace(/^[\r\n\t ]+|[\r\n\t ]+$/g, '')
    .replace(/[ \t]+/g, ' ')
    .replace(/ ?([\r\n]) ?/g, '$1')

and then preserve those line-breaks with

.msg_body {
    white-space: pre; // for IE 6 and 7
    white-space: pre-wrap; // or pre-line
}

or, instead of that CSS, add a .replace(/\r?\n/g, '<br />') after the other JavaScript .replaces.

(Side note: Using document.write() like that is also not ideal and sometimes vulnerable to cross-site scripting attacks, but that's another subject. In relation to this answer, if you wanted to use the variation that replaces with <br>, you'd have to escape <,&(,>,",') before generating the <br>s.)

--

[1] reference: sections "Element White Space Handling" and "XML Schema White Space Control" http://www.usingxml.com/Basics/XmlSpace#ElementWhiteSpaceHandling

[2] http://www.quirksmode.org/css/whitespace.html

[3] except for a few places in Javascript's syntax where its semicolon insertion is particularly annoying.

[4] I wrote it and tested these regexps in Linux Node.js (which uses the same Javascript engine as Chrome, "V8"). There's a small risk some browser executes regexps differently. (My test string (in javascript syntax) "\n\nfoo bar baz\n\n\tmore lyrics \nare good\n\n")

idupree
  • 720
  • 5
  • 16
2
<song>
  <title>Song Tigle</title>
  <lyrics>
    <line>The is the very first line</line>
    <line>Number two and I'm still feeling fine</line>
    <line>Number three and a pattern begins</line>
    <line>Add lines like this and everyone wins!</line>
  </lyrics>
</song>

(Sung to the tune of Home on the Range)

If it was mine I'd wrap the choruses and verses in XML elements as well.

Robusto
  • 29,248
  • 8
  • 52
  • 76
  • Not a bad idea, but too verbose! CDATA works fine here. – fastcodejava Jun 07 '10 at 00:06
  • @fastcodejava: You're a Java guy and you tell me this is verbose? :) Nah, not nearly verbose enough! As I mentioned in my edit, I'd wrap choruses and verses as well. – Robusto Jun 07 '10 at 00:50
1
<description><![CDATA[first line<br/>second line<br/>]]></description>
sohaib
  • 797
  • 1
  • 10
  • 8
1

If you use CDATA, you could embed the line breaks directly into the XML I think. Example:

<song>
    <title>Song Title</title>
    <lyric><![CDATA[Line 1
Line 2
Line 3]]></lyric>
</song>
icktoofay
  • 117,602
  • 18
  • 233
  • 223
  • I tried it, but then the XML file just wouldn't load into the HTML page (resulting in a blank space where the XML is supposed to be loaded to) :( – ew89 Jun 06 '10 at 23:14
  • 1
    This works perfectly well without CDATA. – Tomalak Jun 06 '10 at 23:25
0

If you are using CSS to style (Not recommended.) you can use display:block;, however, this will only give you line breaks before and after the styled element.

Ben
  • 1,865
  • 18
  • 22