Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么';在文本/xml值中编码CR-LF换行符的正确方法是什么?_Xml_Xml Serialization - Fatal编程技术网

什么';在文本/xml值中编码CR-LF换行符的正确方法是什么?

什么';在文本/xml值中编码CR-LF换行符的正确方法是什么?,xml,xml-serialization,Xml,Xml Serialization,与可以做任何事情的application/xml文件,或将所有空白序列转换为单个空格字符的normalizedString值不同,我在这里专门针对具有字符串值的text/xml文件进行提问。为了简单起见,假设我只对UTF8编码的文件使用ASCII字符 给定我希望用XML表示的以下两行文本字符串: Hello World! 这是内存中的以下字节: 0000: 48 65 6c 6c 6f 0d 0a 57 6f 72 6c 64 21 Hello..World! 根据RFC 2046,任何te

与可以做任何事情的application/xml文件,或将所有空白序列转换为单个空格字符的normalizedString值不同,我在这里专门针对具有字符串值的text/xml文件进行提问。为了简单起见,假设我只对UTF8编码的文件使用ASCII字符

给定我希望用XML表示的以下两行文本字符串:

Hello
World!
这是内存中的以下字节:

0000: 48 65 6c 6c 6f 0d 0a 57 6f 72 6c 64 21 Hello..World!
根据RFC 2046,任何text/*MIME类型都必须(不应该)使用回车符后跟换行字符序列来表示换行符。因此,以下XML片段应该是正确的:

<tag>Hello
World!</tag>
你好 世界! 或

0000:3c 74 61 67 3c 48 65 6c 6c 6f 0d 0a 57 6f 72 6c你好..世界
0010:64 21 3c 2f 74 61 67 3c d!
但我经常看到如下文件:

<tag><![CDATA[Hello
World!]]></tag>

更奇怪的是:

<tag>Hello&xD;
World!</tag>
Hello&xD;
世界!
其中&0xD;序列后面跟着一个换行字符:

0000: 3c 74 61 67 3c 48 65 6c 6c 6f 26 78 44 3b 0a 57 <tag>Hello&xD;.W
0010: 6f 72 6c 64 21 3c 2f 74 61 67 3c                orld!</tag>
0000:3c 74 61 67 3c 48 65 6c 6c 6f 26 78 44 3b 0a 57 Hello&xD;。W
0010:6f 72 6c 64 21 3c 2f 74 61 67 3c世界!

我错过了什么?在XML字符串值中表示多行文本的正确方法是什么,以便它可以在另一端不受干扰地显示出来?

CR(&x0D;)、LF(&x0A;)、CRLF或其他一些组合都是有效的。如中所述,所有这些都转换为单个&x0A;字符。

在用Mono编写NUnit测试和用Java编写JUnit测试之后,答案似乎是使用Hello \世界!或者你好 \世界!如下

Foo.cs:

using System.IO;
using System.Text;
using System.Xml.Serialization;

namespace XmlStringTests
{
    public class Foo
    {
        public string greeting;

        public static Foo DeserializeFromXmlString (string xml)
        {
            Foo result;
            using (MemoryStream memoryStream = new MemoryStream()) {
                byte[] buffer = Encoding.UTF8.GetBytes (xml);
                memoryStream.Write (buffer, 0, buffer.Length);
                memoryStream.Seek (0, SeekOrigin.Begin);
                XmlSerializer xs = new XmlSerializer (typeof(Foo));
                result = (Foo)xs.Deserialize (memoryStream);
            }
            return result;
        }
    }
}
XmlStringTests.cs:

using NUnit.Framework;

namespace XmlStringTests
{
    [TestFixture]
    public class XmlStringTests
    {
        const string expected = "Hello\u000d\u000aWorld!";

        [Test(Description="Fails")]
        public void Cdata ()
        {
            const string test = "<Foo><greeting><![CDATA[Hello\u000d\u000aWorld!]]></greeting></Foo>";
            Foo bar = Foo.DeserializeFromXmlString (test);
            Assert.AreEqual (expected, bar.greeting);
        }

        [Test(Description="Fails")]
        public void CdataWithHash13 ()
        {
            const string test = "<Foo><greeting><![CDATA[Hello&#13;\u000aWorld!]]></greeting></Foo>";
            Foo bar = Foo.DeserializeFromXmlString (test);
            Assert.AreEqual (expected, bar.greeting);
        }

        [Test(Description="Fails")]
        public void CdataWithHashxD ()
        {
            const string test = "<Foo><greeting><![CDATA[Hello&#xd;\u000aWorld!]]></greeting></Foo>";
            Foo bar = Foo.DeserializeFromXmlString (test);
            Assert.AreEqual (expected, bar.greeting);
        }

        [Test(Description="Fails")]
        public void Simple ()
        {
            const string test = "<Foo><greeting>Hello\u000d\u000aWorld!</greeting></Foo>";
            Foo bar = Foo.DeserializeFromXmlString (test);
            Assert.AreEqual (expected, bar.greeting);
        }

        [Test(Description="Passes")]
        public void SimpleWithHash13 ()
        {
            const string test = "<Foo><greeting>Hello&#13;\u000aWorld!</greeting></Foo>";
            Foo bar = Foo.DeserializeFromXmlString (test);
            Assert.AreEqual (expected, bar.greeting);
        }

        [Test(Description="Passes")]
        public void SimpleWithHashxD ()
        {
            const string test = "<Foo><greeting>Hello&#xd;\u000aWorld!</greeting></Foo>";
            Foo bar = Foo.DeserializeFromXmlString (test);
            Assert.AreEqual (expected, bar.greeting);
        }
    }
}
XmlStringTests.java:

import static org.junit.Assert.*;
import org.junit.Test;


public class XmlStringTests {
    String expected = "Hello\r\nWorld!";

    @Test //Fails
    public void testCdata ()
    {
        String test = "<Foo><greeting><![CDATA[Hello\r\nWorld!]]></greeting></Foo>";
        Foo bar = Foo.DeserializeFromXmlString (test);
        assertEquals (expected, bar.greeting);
    }

    @Test //Fails
    public void testCdataWithHash13 ()
    {
        String test = "<Foo><greeting><![CDATA[Hello&#13;\nWorld!]]></greeting></Foo>";
        Foo bar = Foo.DeserializeFromXmlString (test);
        assertEquals (expected, bar.greeting);
    }

    @Test //Fails
    public void testCdataWithHashxD ()
    {
        String test = "<Foo><greeting><![CDATA[Hello&#xd;\nWorld!]]></greeting></Foo>";
        Foo bar = Foo.DeserializeFromXmlString (test);
        assertEquals (expected, bar.greeting);
    }

    @Test //Fails
    public void testSimple ()
    {
        String test = "<Foo><greeting>Hello\r\nWorld!</greeting></Foo>";
        Foo bar = Foo.DeserializeFromXmlString (test);
        assertEquals (expected, bar.greeting);
    }

    @Test //Passes
    public void testSimpleWithHash13 ()
    {
        String test = "<Foo><greeting>Hello&#13;\nWorld!</greeting></Foo>";
        Foo bar = Foo.DeserializeFromXmlString (test);
        assertEquals (expected, bar.greeting);
    }

    @Test //Passes
    public void testSimpleWithHashxD ()
    {
        String test = "<Foo><greeting>Hello&#xd;\nWorld!</greeting></Foo>";
        Foo bar = Foo.DeserializeFromXmlString (test);
        assertEquals (expected, bar.greeting);
    }
}
import static org.junit.Assert.*;
导入org.junit.Test;
公共类XmlStringTests{
字符串应为=“Hello\r\nWorld!”;
@测试//失败
公共void testCdata()
{
字符串测试=”;
Foo bar=Foo.DeserializeFromXmlString(测试);
assertEquals(预期,酒吧问候语);
}
@测试//失败
public void testCdataWithHash13()
{
字符串测试=”;
Foo bar=Foo.DeserializeFromXmlString(测试);
assertEquals(预期,酒吧问候语);
}
@测试//失败
公共void TestCDATA WithHashXD()
{
字符串测试=”;
Foo bar=Foo.DeserializeFromXmlString(测试);
assertEquals(预期,酒吧问候语);
}
@测试//失败
公共void testSimple()
{
字符串测试=“你好\r\nWorld!”;
Foo bar=Foo.DeserializeFromXmlString(测试);
assertEquals(预期,酒吧问候语);
}
@测试//通过
public void testSimpleWithHash13()
{
String test=“你好
;\nWorld!”;
Foo bar=Foo.DeserializeFromXmlString(测试);
assertEquals(预期,酒吧问候语);
}
@测试//通过
public void testSimpleWithHashxD()
{
String test=“你好
;\nWorld!”;
Foo bar=Foo.DeserializeFromXmlString(测试);
assertEquals(预期,酒吧问候语);
}
}

我希望这能节省一些人的时间。

根据相同的规范,CR(#d)是CDATA块中的有效字符,因此不应进行转换。我将从CR LF输入中获取LF定义为被骚扰。有没有一种方法可以正确地对XML进行编码,以使CR LF在接收端返回,或者XML只是被破坏了,不适合文本/XML MIME类型?在阅读规范时,我将其解释为:如果在输入中发现以下任何原始代码点序列,请将其替换为
0xd 0xa
0xd 0x85
0x85
0x2028
0xd«除0xa或0x85以外的任何内容
。由于此替换发生在“解析之前”(请参阅参考资料),因此应保留任何文字字符实体(即
和#xd
)。因此,对于该示例,解析的内容应该是字节序列
0xd
,而不是
0xa
。我读的规范正确吗?您的答案似乎表明此替换可能发生在解析之后,而不是之前…
import java.io.StringReader;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name = "Foo")
@XmlType(propOrder = { "greeting" })
public class Foo {
    public String greeting;

    public static Foo DeserializeFromXmlString(String xml) {
        try {
            JAXBContext context = JAXBContext.newInstance(Foo.class);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            Foo foo = (Foo) unmarshaller.unmarshal(new StringReader(xml));
            return foo;
        } catch (JAXBException e) {
            e.printStackTrace();
            return null;
        }
    }
}
import static org.junit.Assert.*;
import org.junit.Test;


public class XmlStringTests {
    String expected = "Hello\r\nWorld!";

    @Test //Fails
    public void testCdata ()
    {
        String test = "<Foo><greeting><![CDATA[Hello\r\nWorld!]]></greeting></Foo>";
        Foo bar = Foo.DeserializeFromXmlString (test);
        assertEquals (expected, bar.greeting);
    }

    @Test //Fails
    public void testCdataWithHash13 ()
    {
        String test = "<Foo><greeting><![CDATA[Hello&#13;\nWorld!]]></greeting></Foo>";
        Foo bar = Foo.DeserializeFromXmlString (test);
        assertEquals (expected, bar.greeting);
    }

    @Test //Fails
    public void testCdataWithHashxD ()
    {
        String test = "<Foo><greeting><![CDATA[Hello&#xd;\nWorld!]]></greeting></Foo>";
        Foo bar = Foo.DeserializeFromXmlString (test);
        assertEquals (expected, bar.greeting);
    }

    @Test //Fails
    public void testSimple ()
    {
        String test = "<Foo><greeting>Hello\r\nWorld!</greeting></Foo>";
        Foo bar = Foo.DeserializeFromXmlString (test);
        assertEquals (expected, bar.greeting);
    }

    @Test //Passes
    public void testSimpleWithHash13 ()
    {
        String test = "<Foo><greeting>Hello&#13;\nWorld!</greeting></Foo>";
        Foo bar = Foo.DeserializeFromXmlString (test);
        assertEquals (expected, bar.greeting);
    }

    @Test //Passes
    public void testSimpleWithHashxD ()
    {
        String test = "<Foo><greeting>Hello&#xd;\nWorld!</greeting></Foo>";
        Foo bar = Foo.DeserializeFromXmlString (test);
        assertEquals (expected, bar.greeting);
    }
}