Javascript 流解析 xml
Javascript stream parse xml
我有几个 xml 文件,我想在 Javascript 中过滤以填充 google 图表散点图。
问题是,我必须使用流解析,因为每个文件都非常大,超过 3.5 MB。
如何将 4MB xml 文件中的数据传递到 javascript 数组中,我可以在 运行 内存不足的情况下循环遍历
示例:
<?xml version="1.0" encoding="UTF-8"?>
<rootNode a="1">
<parentNode b="2" c="3" d="4">
<childNode e="5" f="7" g="7"/>
<childNode e="2" f="9" g="4"/>
<childNode e="11" f="7" g="3"/>
...
</parentNode>
</rootNode>
到
var chart = [],
fIsSeven = [],
childNode = /*Each node of xml*/;
// Filter results and save data to 2D array
foreach (childNode) {
if(f == 7) {
fIsSeven = [e, g];
chart.push(fIsSeven);
}
}
...
// Use array to populate google chart
function drawChart() {
var data = google.visualization.arrayToDataTable([
['e', 'g'],
forEach (chart) {
[e, g]
}
]);
...
}
我发现从大型 xml 文件加载 google 数据 table 的最快方法是使用 xsl 将数据转换为 google's json format,然后创建数据 table 直接来自 json...
以下是来自用于加载 google...
的 cognos 报告的 XML 数据示例
XML
<metadata>
<item name="Level 1" type="xs:string" length="38"/>
<item name="Level 2" type="xs:string" length="302"/>
<item name="Level 3" type="xs:string" length="302"/>
<item name="Level 4" type="xs:string" length="302"/>
<item name="Level 5" type="xs:string" length="302"/>
<item name="Expenditure Group" type="xs:string" length="48"/>
<item name="GL Number" type="xs:double" precision="2"/>
<item name="Actual" type="xs:double" precision="2"/>
<item name="Budget" type="xs:double" precision="2"/>
<item name="Forecast" type="xs:double" precision="2"/>
<item name="Category" type="xs:string" length="102"/>
</metadata>
<data>
<row>
<value>SBU</value>
<value>BU</value>
<value>Department</value>
<value>Office</value>
<value>Site</value>
<value>Expense</value>
<value>3</value>
<value>13811.22</value>
<value>6175</value>
<value>13811.22</value>
<value>Category</value>
</row>
<row>
<value>SBU</value>
<value>BU</value>
<value>Department</value>
<value>Office</value>
<value>Site</value>
<value>Expense</value>
<value>3</value>
<value>13811.22</value>
<value>6175</value>
<value>13811.22</value>
<value>Category</value>
</row>
...
以下是用于将 XML 转换为 google 的 JSON 格式的 XSL...
XSL
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns="http://tempuri.org/"
xmlns:cog="http://developer.cognos.com/schemas/xmldata/1/"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:output method="text" omit-xml-declaration="yes" indent="no" />
<xsl:template match="/">
{
"cols": [
{"label": "SBU", "type": "string"},
{"label": "BU", "type": "string"},
{"label": "Department", "type": "string"},
{"label": "Office", "type": "string"},
{"label": "Site", "type": "string"},
{"label": "Expenditure Group", "type": "string"},
{"label": "Period", "type": "number", "p": {"format": "d2"}},
{"label": "Actual", "type": "number", "p": {"format": "n2"}},
{"label": "Budget", "type": "number", "p": {"format": "n2"}},
{"label": "Forecast", "type": "number", "p": {"format": "n2"}},
{"label": "O&M Category", "type": "string"}
],
"rows": [
<xsl:for-each select="//cog:row">
{"c":[
{"v": "<xsl:value-of select="cog:value[1]" />"},
{"v": "<xsl:value-of select="cog:value[2]" />"},
{"v": "<xsl:value-of select="cog:value[3]" />"},
{"v": "<xsl:value-of select="cog:value[4]" />"},
{"v": "<xsl:value-of select="cog:value[5]" />"},
{"v": "<xsl:value-of select="cog:value[6]" />"},
{"v": <xsl:value-of select="cog:value[7]" />},
{"v": <xsl:value-of select="cog:value[8]" />},
{"v": <xsl:value-of select="cog:value[9]" />},
{"v": <xsl:value-of select="cog:value[10]" />},
{"v": "<xsl:value-of select="cog:value[11]" />"}
]}<xsl:if test="position() != last()">,</xsl:if>
</xsl:for-each>
]
}
</xsl:template>
</xsl:stylesheet>
以下是 JavaScript 执行转换的片段...
JavaScript
// create xsl processor
var xslProcessor = new XSLTProcessor();
xslProcessor.importStylesheet(sender.target.responseXML); // responseXML = result from loading xsl file above
// perform transformation
var jsonData = xslProcessor.transformToFragment(sender.get_xml(), document).textContent; // get_xml() = result from loading xml file above
// load google data table
dataTableSummary = new google.visualization.DataTable(jsonData);
使用这种方法,在 google chrome...
加载 3.1 MB 的 XML 数据平均需要 1.1 秒
加载 3.6 MB 的 XML 数据平均需要 1.4 秒
其中包括通过 XMLHttpRequest
加载 XML 和 XSL 文件的时间
单独执行转换所花费的时间,3.6 MB 大约需要 300 毫秒...
没有遇到过 运行 内存不足 的任何问题...
我有几个 xml 文件,我想在 Javascript 中过滤以填充 google 图表散点图。
问题是,我必须使用流解析,因为每个文件都非常大,超过 3.5 MB。
如何将 4MB xml 文件中的数据传递到 javascript 数组中,我可以在 运行 内存不足的情况下循环遍历
示例:
<?xml version="1.0" encoding="UTF-8"?>
<rootNode a="1">
<parentNode b="2" c="3" d="4">
<childNode e="5" f="7" g="7"/>
<childNode e="2" f="9" g="4"/>
<childNode e="11" f="7" g="3"/>
...
</parentNode>
</rootNode>
到
var chart = [],
fIsSeven = [],
childNode = /*Each node of xml*/;
// Filter results and save data to 2D array
foreach (childNode) {
if(f == 7) {
fIsSeven = [e, g];
chart.push(fIsSeven);
}
}
...
// Use array to populate google chart
function drawChart() {
var data = google.visualization.arrayToDataTable([
['e', 'g'],
forEach (chart) {
[e, g]
}
]);
...
}
我发现从大型 xml 文件加载 google 数据 table 的最快方法是使用 xsl 将数据转换为 google's json format,然后创建数据 table 直接来自 json...
以下是来自用于加载 google...
的 cognos 报告的 XML 数据示例XML
<metadata>
<item name="Level 1" type="xs:string" length="38"/>
<item name="Level 2" type="xs:string" length="302"/>
<item name="Level 3" type="xs:string" length="302"/>
<item name="Level 4" type="xs:string" length="302"/>
<item name="Level 5" type="xs:string" length="302"/>
<item name="Expenditure Group" type="xs:string" length="48"/>
<item name="GL Number" type="xs:double" precision="2"/>
<item name="Actual" type="xs:double" precision="2"/>
<item name="Budget" type="xs:double" precision="2"/>
<item name="Forecast" type="xs:double" precision="2"/>
<item name="Category" type="xs:string" length="102"/>
</metadata>
<data>
<row>
<value>SBU</value>
<value>BU</value>
<value>Department</value>
<value>Office</value>
<value>Site</value>
<value>Expense</value>
<value>3</value>
<value>13811.22</value>
<value>6175</value>
<value>13811.22</value>
<value>Category</value>
</row>
<row>
<value>SBU</value>
<value>BU</value>
<value>Department</value>
<value>Office</value>
<value>Site</value>
<value>Expense</value>
<value>3</value>
<value>13811.22</value>
<value>6175</value>
<value>13811.22</value>
<value>Category</value>
</row>
...
以下是用于将 XML 转换为 google 的 JSON 格式的 XSL...
XSL
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns="http://tempuri.org/"
xmlns:cog="http://developer.cognos.com/schemas/xmldata/1/"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:output method="text" omit-xml-declaration="yes" indent="no" />
<xsl:template match="/">
{
"cols": [
{"label": "SBU", "type": "string"},
{"label": "BU", "type": "string"},
{"label": "Department", "type": "string"},
{"label": "Office", "type": "string"},
{"label": "Site", "type": "string"},
{"label": "Expenditure Group", "type": "string"},
{"label": "Period", "type": "number", "p": {"format": "d2"}},
{"label": "Actual", "type": "number", "p": {"format": "n2"}},
{"label": "Budget", "type": "number", "p": {"format": "n2"}},
{"label": "Forecast", "type": "number", "p": {"format": "n2"}},
{"label": "O&M Category", "type": "string"}
],
"rows": [
<xsl:for-each select="//cog:row">
{"c":[
{"v": "<xsl:value-of select="cog:value[1]" />"},
{"v": "<xsl:value-of select="cog:value[2]" />"},
{"v": "<xsl:value-of select="cog:value[3]" />"},
{"v": "<xsl:value-of select="cog:value[4]" />"},
{"v": "<xsl:value-of select="cog:value[5]" />"},
{"v": "<xsl:value-of select="cog:value[6]" />"},
{"v": <xsl:value-of select="cog:value[7]" />},
{"v": <xsl:value-of select="cog:value[8]" />},
{"v": <xsl:value-of select="cog:value[9]" />},
{"v": <xsl:value-of select="cog:value[10]" />},
{"v": "<xsl:value-of select="cog:value[11]" />"}
]}<xsl:if test="position() != last()">,</xsl:if>
</xsl:for-each>
]
}
</xsl:template>
</xsl:stylesheet>
以下是 JavaScript 执行转换的片段...
JavaScript
// create xsl processor
var xslProcessor = new XSLTProcessor();
xslProcessor.importStylesheet(sender.target.responseXML); // responseXML = result from loading xsl file above
// perform transformation
var jsonData = xslProcessor.transformToFragment(sender.get_xml(), document).textContent; // get_xml() = result from loading xml file above
// load google data table
dataTableSummary = new google.visualization.DataTable(jsonData);
使用这种方法,在 google chrome...
加载 3.1 MB 的 XML 数据平均需要 1.1 秒
加载 3.6 MB 的 XML 数据平均需要 1.4 秒
其中包括通过 XMLHttpRequest
单独执行转换所花费的时间,3.6 MB 大约需要 300 毫秒...
没有遇到过 运行 内存不足 的任何问题...