XSLT - 偷偷摸摸的插入(xsl:copy)

时间:2012-09-28 11:02:06

标签: java xml xslt xml-parsing stax

我将从代码开始 - 我们都喜欢代码:D

XML:

    <report>
        <subject>
            <subjectId>1</subjectId>
            <name>John</name>
            <surname>Doe</surname>
        </subject>
        <subject>
            <subjectId>2</subjectId>
            <name>Frank</name>
            <surname>Timothy</surname>
        </subject>
        <individual>
            <individualId>10</individualId>
            <name>Isaac</name>
            <surname>Newton</surname>
            <co-worker>
                <subject>
                    <subjectId>1</subjectId>
                    <inXml>true</inXml>
                </subject>
                <subject>
                    <subjectId>2</subjectId>
                    <inXml>true</inXml>
                </subject>
            </co-worker>
        </individual>

        <owner>
            <subject>
                <subjectId>2</subjectId>
                <inXml>true</inXml>
            </subject>
            <share>100</share>
        </owner>

        <individual>
            <individualId>10</individualId>
            <inXml>true</inXml>
        </individual>
    </report>

XML 2:

    <report>
        <owner>
            <individual>
                <individualId>10</individualId>
                <inXml>true</inXml>
            </individual>
        </owner>
        <individual>
            <individualId>2</individualId>
            <name>John</name>
            <surname>Doe</surname>
            <co-worker>
                <individual>
                    <individualId>10</individualId>
                    <inXml>true</inXml>
                </individual>
            </co-worker>
        </individual>
        <individual>
            <individualId>10</individualId>
            <name>Isaac</name>
            <surname>Newton</surname>
            <co-worker>
                <individual>
                    <individualId>2</individualId>
                    <inXml>true</inXml>
                </individual>
            </co-worker>
        </individual>

    </report>

XSLT:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
        <xsl:output method="xml" indent="yes" />

        <xsl:template match="individual[inXml='true']">
            <xsl:variable name="indId" select="./individualId/text()" />
            <xsl:variable name="result" select="//individual[not(inXml) and individualId=$indId]/*" />
            <xsl:choose>
                <xsl:when test="$result != ''">
                    <xsl:copy>
                        <xsl:apply-templates select="$result" />
                    </xsl:copy>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:copy-of select="." />
                </xsl:otherwise>
            </xsl:choose>
        </xsl:template>

        <xsl:template match="subject[inXml='true']">
            <xsl:variable name="subId" select="./subjectId/text()" />
            <xsl:variable name="result" select="//subject[not(inXml) and subjectId=$subId]/*" />
            <xsl:choose>
                <xsl:when test="$result != ''">
                    <xsl:copy>
                        <xsl:apply-templates select="$result" />
                    </xsl:copy>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:copy-of select="." />
                </xsl:otherwise>
            </xsl:choose>
        </xsl:template>

        <xsl:template match="@* | node()">
            <xsl:copy>
                <xsl:apply-templates select="@* | node()" />
            </xsl:copy>
        </xsl:template>

    </xsl:stylesheet>

我想要实现的目标是什么? - 我想在出现“inXml”标签的地方复制主题/个人。 XSLT似乎工作..但是稍微大一点xmls ..大约1MB(它不大......) 我的java应用程序因java.lang.OutOfMemoryError失败:Java堆空间。 我将流重定向到文件......令人惊讶的是 - 带有转换结果的文件随着光速的增长而增长 - 在15秒后大约300mb! :D hehehe - 这证明我的xlst中必定存在一些错误,导致无限循环。

重要的是 - 在复制节点时,可能会发生内部已经存在“inXml” - 这就是我应用模板或结果的原因。我准备的XML描述了这个问题。

编辑: XML2很可能完全弄乱我的应用程序。我该如何解决?我希望通过XSLT修复我的jaxb解组问题 - 这不是我所知道的解决方案 - 我需要在解组过程中插入对象的引用,而不是在那里尝试插入更多的XML节点。我怎样才能做到这一点?

提前谢谢!

1 个答案:

答案 0 :(得分:0)

如果数据中存在循环,您的代码将进入无限递归。

我怀疑条件not(inXml)应为not(inXML='true')以防止这种情况发生;但不知道你的数据,我不能确定。