C# 3.0中优化压缩XML的最佳方法

4

编码平台:ASP.NET C#

我有一个像这样的XML。

<Items>
    <Map id="35">
        <Terrains>
            <Item id="1" row="0" column="0"/>
            <Item id="1" row="0" column="1"/>
            <Item id="1" row="0" column="2"/>
            <Item id="1" row="0" column="3"/>
            <Item id="1" row="0" column="4"/>
        </Terrains>
    </Map>
</Items>

我希望您能将此缩小为:
<Its>
    <Map id="30">
        <Te>
            <It id="1" r="0" c="0"/>
            <It id="1" r="0" c="1"/>
            <It id="1" r="0" c="2"/>
            <It id="1" r="0" c="3"/>
            <It id="1" r="0" c="4"/>
        </Te>
    </Map>
</Its>

然后我使用James Newton-King的JSON转换器将其转换为JSON。
这个想法是将xml数据最小化,因为它包含了成千上万行。

我的问题是:

  1. 如上所述,最小化xml的最佳方法是什么?
  2. 现在是通过XML-MinifyXML-转换为JSON完成的。 我可以分两步完成吗?(XML-Minify同时转换为JSON)
  3. 对于这种简单的转换,James Newton-King的JSON转换器是否有点过度?

如果可能,请提供代码片段。


3
这并不是XML的最小化,因为这会改变语义(JavaScript的最小化可能会更改本地变量的名称,但它们不在那些函数之外使用)。XML的最小化主要是避免重复冗长的命名空间标签、消除无意义的空格等。 - Richard
@Richard:那我应该叫它什么?打包? - naveen
1
“使用较短的标识符”,任何使用XML的消费者都需要能够提取数据,因此它需要知道节点名称。因此,转换将是固定的。 - Richard
XML文档应该易于阅读且相对清晰,XML标记中的简洁性并不是最重要的。 - Caspar Kleijne
@Caspar:我不同意简洁性总是最不重要的观点。它是一个很好的交换格式,但有时要交换的数据量与系统的处理能力相比是相当大的。 - Eric J.
@CasparKleijne:这是为了一个大型多人在线游戏。减小文件大小非常重要。 - naveen
1个回答

5
我怀疑使用GZIP(通过GZipStream或仅通过IIS,需要启用json mime-type的动态压缩)会更简单、更小,但如果您正在使用序列化,只需添加一些[XmlElement(...)] / [XmlAttribute(...)]即可。当然,如果尺寸是您关心的问题,我也可以建议使用像protobuf-net这样的东西,它提供了极其紧凑的二进制输出。
如果您没有使用序列化,那么这看起来是一种理想的“xslt”方案:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="@* | node()">
    <xsl:copy><xsl:apply-templates select="@* | node()"/></xsl:copy>
  </xsl:template>
  <xsl:template match="/Items">
    <Its><xsl:apply-templates/></Its>
  </xsl:template>
  <xsl:template match="/Items/Map/Terrains">
    <Te><xsl:apply-templates/></Te>
  </xsl:template>
  <xsl:template match="/Items/Map/Terrains/Item">
    <It id="{@id}" r="{@row}" c="{@column}"><xsl:apply-templates select="*"/></It>
  </xsl:template>
</xsl:stylesheet>

(使用C#:)
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load("Condense.xslt"); // cache and re-use this object; don't Load each time
xslt.Transform("Data.xml", "Smaller.xml");

 Console.WriteLine("{0} vs {1}",
    new FileInfo("Data.xml").Length,
    new FileInfo("Smaller.xml").Length);

谢谢。但是我从SWF获取这个XML作为输入,.NET部分是将XML进行缩小(或者说打包),然后转换为JSON,以便大小更小。我将JSON保存在另一个位置供另一个SWF访问。 - naveen
1
@naveen - XSLT 路线,示例已添加 - Marc Gravell
1
@naveen 你可以使用 LINQ-XML,但是 XSLT 是专为转换 XML 设计的便利工具。 - Marc Gravell
谢谢你的代码片段。我真的很需要它。 - naveen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接