【问题标题】:Nesting xml/CDATA into a xml file?将 xml/CDATA 嵌套到 xml 文件中?
【发布时间】:2011-12-28 18:15:14
【问题描述】:

我需要将一个相当大的 xml 文件放入另一个 xml 文件中。我考虑过为此使用 CDATA:

http://www.w3.org/TR/2000/REC-xml-20001006#sec-cdata-sect http://www.w3schools.com/xml/xml_cdata.asp

但由于我的 xml 也可能包含 CDATA,除非我做一些讨厌的解决方法,否则这不起作用:

http://web-design.blogs.webucator.com/2010/11/20/nesting-cdata-blocks/

有没有更好的方法来传输/编码大型嵌套 xml 文件,或者 xml 格式根本不适合以这种方式使用?

【问题讨论】:

  • 现在这个“讨厌的解决方法”的链接已经消失了。这个解决方法到底是什么?
  • @TomaszGandor 我相信这和stackoverflow.com/a/36331725/746461是一样的技巧

标签: xml cdata


【解决方案1】:

是的,在您最顶层的文档中创建数据类型 bin.base64 的 CDATA 部分。这样,即使您包装的文档包含 CDATA 部分,您也会受到保护。另外,您的应用程序还将支持二进制文件(图像、电子表格等)。

这里有一些基于 Microsoft ADO 和 MSXML 的代码。

function wrapBinaryFile( strFileName)
{
    var ado_stream = new ActiveXObject("ADODB.Stream");
    var xml = newXMLDocument();
    xml.loadXML("<file/>");
    xml.documentElement.setAttribute( "name", strFileName );

    xml.documentElement.setAttribute("xmlns:dt","urn:schemas-microsoft-com:datatypes");

    xml.documentElement.dataType = "bin.base64";
    ado_stream.Type = 1; // 1=adTypeBinary
    ado_stream.Open();
    ado_stream.LoadFromFile( strFileName );
    xml.documentElement.nodeTypedValue = ado_stream.Read(-1); // -1=adReadAll
    ado_stream.Close();
    return xml;
}

以及如何在另一端解开它......

function unwrapBinaryFile(ndFile, strFileName )
{
    var ado_stream = new ActiveXObject("ADODB.Stream");
    ndFile.dataType = "bin.base64";

    ado_stream.Type = 1; // 1=adTypeBinary
    ado_stream.Open();
    ado_stream.write( ndFile.nodeTypedValue );
    ado_stream.SaveToFile( strFileName, 2 );
    ado_stream.Close(); 
}

【讨论】:

  • 你能在 HttpWebRequest 上做类似的事情吗?我需要能够在 HttpWebRequest 中嵌套 CDATA 标记。谢谢!
  • 当然,创建一个 bin.base64 XML 文档,然后通过 HTTP 请求发布。记住您在 XML 中的包装。您如何处理生成的 XML(保存到磁盘、发布到服务器)取决于您。
  • 如何在 HttpWebRequest 上指定内容类型以允许嵌套 CDATA?由于 stringData 中的嵌套 CDATA,我有以下代码无法显示在服务器上: HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(Url); myReq.Method = "POST"; byte[] lbPostBuffer = System.Text.Encoding.GetEncoding(1252).GetBytes(stringData); myReq.ContentType = "文本/xml; charset=utf-8"; myReq.Accept = "文本/xml";
  • stackoverflow.com/questions/17535872/… 一个很好的例子
  • 感谢您的帮助。我通过使用带有模型的 HttpClient 和带有 Web api 框架的序列化解决了我的问题。
【解决方案2】:

第一个 XML:

<root>
    <data1 value="test1" />
    <data2>
        <value>test2</value>
    </data2>
</root>

第二个 XML:

<root2>
    <data3 value="test3" />
    <data4>
        <value>test4</value>
    </data2>
</root2>

您可以在第一个特定节点中包含第二个 XML:

<root>
    <data1 value="test1" />
    <data2>
        <value>test2</value>
    </data2>
    <dataFromSecondXML>
        <data3 value="test3" />
        <data4>
            <value>test4</value>
        </data2>
    </dataFromSecondXML>
</root>

【讨论】:

  • &lt;dataFromSecondXML&gt; 在技术上是一个 any 元素。这是嵌入 XML 元素的一种方式,但不是 XML 文档。
【解决方案3】:

简短的回答是 XML 不应该以这种方式使用!

但是,如果您对要打包的 XML 文件进行 base64 编码,则编码结果将不包含任何可能被解释为标记或实体引用的字符,并且可以安全地保存为文本节点的内容。

【讨论】:

  • 如果 XML 文档不嵌入到其他 XML 文档中,我猜 XSLT 和 SOAP 有问题。
  • XML 元素当然可以嵌入到其他 XML 文档中:但是 XML 文档应该包含一个 XML 声明,该声明只能出现在文档的位置,因此如果不以某种方式编码就不能嵌入。
  • 解决这个问题通常很容易。无论是使用 SAX 或 DOM 还是其他一些技术,仅使用根节点作为元素或将元素转换为新文档都非常容易。如果指定的编码不再合适,复制 XML 声明甚至会被证明是有害的。
【解决方案4】:

XML 是分层的:为什么不能直接嵌套文档而不使用 CDATA?除了 DTD 问题,任何 XML 文档都可以复制为另一个文档中元素的内容。

【讨论】:

    【解决方案5】:

    你可以用]]]]>

    替换内部的]]

    (基于http://web-design.blogs.webucator.com/2010/11/20/nesting-cdata-blocks/

    示例:我们有外部和内部文档,我们希望将内部作为 CDATA 放在外部内部。

    <outer>
      <e1 name="abc"/>
      <innerDoc><![CDATA[
          <Doc1/>
        ]]></innerDoc>
    </outer>
    
    <inner>
      <innrer1/>
      <a><![CDATA[
          free text with << >
        ]]></a>
      <innrer2/>
    </inner>
    

    如果我们只是复制和粘贴,我们会得到一个无效的 xml

    <outer>
      <e1 name="abc"/>
      <innerDoc><![CDATA[
          <inner>
            <innrer1/>
            <a><![CDATA[
                free text with << >
              ]]></a>
            <innrer2/>
          </inner>
        ]]></innerDoc>
    </outer>
    

    但是,如果我们将内部的 ]] 替换为 ]]]]>

    <outer>
      <e1 name="abc"/>
      <innerDoc><![CDATA[
          <inner>
            <innrer1/>
            <a><![CDATA[
                free text with << >
              ]]]]><![CDATA[></a>
            <innrer2/>
          </inner>
        ]]></innerDoc>
    </outer>
    

    【讨论】:

      猜你喜欢
      • 2013-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-05
      • 1970-01-01
      相关资源
      最近更新 更多