【发布时间】:2017-02-08 13:46:12
【问题描述】:
我在使用 XSLT 转换大数据集(主机上的 60 GB/50000 圆柱体)时遇到问题。 程序在大型机上运行,所以我没有得到他需要的 2 GB Headsize。 但我不明白他为什么需要这么多空间,也许有办法用更少的空间进行转换?我对XSLT一无所知,我需要一半时间才能做到这一点^^
我的问题: 在 XML 中有许多我不需要的 XML 标记(在示例 person_id、Iso_laender_code 中),我想过滤,所以我只得到我需要的那些。
我的 XML: 我有很多人的标签:
<ndm_message><message>
<Person>...</Person>
<Person>...</Person>
<Person>...</Person>...
每个人都有诸如姓名、地址等标签以及我不需要的许多标签
<Person>
<person_id>24</person_id>
<name>Person's Name</name>
</titel>
<Adresse>
<strasse>Irgendwo</strasse>
<iso_laender_code>004</iso_laender_code>
</Adresse>
</Person
我的 XSLT: 我定义了一个白名单并根据白名单检查每个人的任何节点:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsi:WhiteList>
<name>Person</name>
<name>name</name>
<name>Adresse</name>
<name>strasse</name>
</xsi:WhiteList>
<xsl:template match="/">
<ndm_message>
<xsl:for-each select="ndm_message/message/Person">
<xsl:call-template name="filter" >
<xsl:with-param name="Knoten" select="."/>
</xsl:call-template>
</xsl:for-each>
</ndm_message>
</xsl:template>
<xsl:template name="filter">
<xsl:param name="Knoten" />
<xsl:if test="$Knoten[name()=document('')/*/xsi:WhiteList/*]">
<xsl:copy>
<xsl:if test="not(child::*)">
<xsl:value-of select="$Knoten"/>
</xsl:if>
<xsl:for-each select="$Knoten/*">
<xsl:call-template name="filter" >
<xsl:with-param name="Knoten" select="."/>
</xsl:call-template>
</xsl:for-each>
<!-- -->
</xsl:copy>
</xsl:if>
</xsl:template>
我使用 saxon9.jar 在 Java 中运行 XSLT。
public static void simpleTransform(String sourcePath, String xsltPath,
String resultDir) {
System.setProperty("javax.xml.transform.TransformerFactory",
"net.sf.saxon.TransformerFactoryImpl");
TransformerFactory tFactory = TransformerFactory.newInstance();
try {
Transformer transformer =
tFactory.newTransformer(new StreamSource(new File(xsltPath)));
transformer.transform(new StreamSource(new File(sourcePath)),
new StreamResult(new File(resultDir)));
} catch (Exception e) {
e.printStackTrace();
}
}
有人知道他为什么需要这么多空间吗?我认为 XSLT 只引用一个 Person 并且标签是递归的,一个 /Person 大约是 32 KB。 也许问题是 StreamSource 和 Result? 有没有其他方法可以使用 XSLT 和更少的空间来做到这一点?
非常感谢 弗洛里安
【问题讨论】:
-
Saxon 9 EE 可能允许您使用流式传输运行 XSLT 3.0 样式表,其中 XSLT 处理器与构建完整 XML 输入树的正常 XSLT 处理模型相反,通过输入流以仅转发模式。但是,这需要 Saxon EE 的许可证并重写 XSLT 以允许这种处理。