我有一个带有000行的xml文件,其元素只有一些显示在各种属性和元素内容中的子字符串不同。
所以我想'压缩'xml并通过在运行时用已知的替换替换已知的子字符串来动态创建样式表。 考虑到我对它们的了解,样式表方法似乎是这个问题的优雅解决方案,但如果它有效,我真的不介意我如何得到解决方案。
这个主体需要是通用的,即适用于子节点'n级深'的xml元素 例如
'浓缩'xml可能看起来像
<element id="11[substitute here]11">
<name>[substitute here]</name>
<settings>
<setting>
<name>[substitute here]Setting</name>
<!-- could be more elements here, n levels deep -->
</setting>
</settings>
<moreConfig>zz[substitute here]zz</moreConfig>
</element>
扩展xml,用'aaa'代替'[substitute here]'然后用'bbb'代替
<element id="11aaa11">
<name>aaa</name>
<settings>
<setting>
<name>aaaSetting</name>
<!-- could more elements here, n levels deep -->
</setting>
</settings>
<moreConfig>zzaaazz</moreConfig>
</element>
<element id="11bbb11">
<name>bbb</name>
<settings>
<setting>
<name>bbbSetting</name>
<!-- could more elements here, n levels deep -->
</setting>
</settings>
<calendar>zzbbbzz</calendar>
</element>
我在java 6中这样做,所以我的理解是如果使用xsl只支持1.0。
希望我能清楚地概述这个问题,感谢任何帮助!
非常感谢答案 0 :(得分:1)
这种转变:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:reps>
<r>aaa</r>
<r>bbb</r>
</my:reps>
<xsl:variable name="vReps"
select="document('')/*/my:reps/r"/>
<xsl:template match="node()|@*">
<xsl:param name="pCurrentRep"/>
<xsl:copy>
<xsl:apply-templates select="node()|@*">
<xsl:with-param name="pCurrentRep" select="$pCurrentRep"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="config">
<xsl:param name="pCurrentRep"/>
<xsl:variable name="vDoc" select="."/>
<xsl:copy>
<xsl:for-each select="$vReps">
<xsl:apply-templates select="$vDoc/*">
<xsl:with-param name="pCurrentRep" select="."/>
</xsl:apply-templates>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="@*[contains(., '[substitute here]')]"
priority="2">
<xsl:param name="pCurrentRep"/>
<xsl:attribute name="{name()}">
<xsl:call-template name="replace">
<xsl:with-param name="pRep" select="$pCurrentRep"/>
</xsl:call-template>
</xsl:attribute>
</xsl:template>
<xsl:template match="text()[contains(., '[substitute here]')]"
priority="2">
<xsl:param name="pCurrentRep"/>
<xsl:call-template name="replace">
<xsl:with-param name="pRep" select="$pCurrentRep"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="replace">
<xsl:param name="pText" select="."/>
<xsl:param name="pTarget" select="'[substitute here]'"/>
<xsl:param name="pRep"/>
<xsl:if test="string-length($pText) >0">
<xsl:choose>
<xsl:when test="not(contains($pText, $pTarget))">
<xsl:value-of select="$pText"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring-before($pText, $pTarget)"/>
<xsl:value-of select="$pRep"/>
<xsl:call-template name="replace">
<xsl:with-param name="pText" select=
"substring-after($pText, $pTarget)"/>
<xsl:with-param name="pTarget" select="$pTarget"/>
<xsl:with-param name="pRep" select="$pRep"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档:
<config>
<element id="11[substitute here]11">
<name>[substitute here]</name>
<settings>
<setting>
<name>[substitute here]Setting</name>
<!-- could be more elements here, n levels deep -->
</setting>
</settings>
<moreConfig>zz[substitute here]zz</moreConfig>
</element>
</config>
生成想要的正确结果:
<config>
<element id="11aaa11">
<name>aaa</name>
<settings>
<setting>
<name>aaaSetting</name><!-- could be more elements here, n levels deep -->
</setting>
</settings>
<moreConfig>zzaaazz</moreConfig>
</element>
<element id="11bbb11">
<name>bbb</name>
<settings>
<setting>
<name>bbbSetting</name><!-- could be more elements here, n levels deep -->
</setting>
</settings>
<moreConfig>zzbbbzz</moreConfig>
</element>
</config>