我有一组文档隐式定义第二组对象的允许字段,这些对象必须转换为第三组文档( 哪个“规则”文档使用取决于被转换文件的内容,例如
<!-- One example rules document -->
<document object="obj1_rules">
<field name="A"/>
<field name="B"/>
<field name="C"/>
</document>
<!-- Document to be tranformed based upon obj1_rules-->
<document object="obj1">
<field name="A"/>
<field name="B"/>
<field name="C"/>
<field name="D"/>
<field name="E"/>
</document>
<!-- Desired result-->
<document object="obj1">
<newfield name="A"/>
<newfield name="B"/>
<newfield name="C"/>
</document>
是否可以使用xslt进行此转换?
我看到"There is no way in XSLT of constructing XPath expressions (e.g. variable references) at run-time."所以我运气不好,或者我只是错误地看待这个问题?谢谢!
答案 0 :(得分:2)
这是一个简单的解决方案:
此转化:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- -->
<xsl:variable name="vrtfRules">
<document object="obj1_rules">
<field name="A"/>
<field name="B"/>
<field name="C"/>
</document>
</xsl:variable>
<!-- -->
<xsl:variable name="vRules" select=
"document('')/*/xsl:variable
[@name = 'vrtfRules']
/*
"/>
<!-- -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- -->
<xsl:template match="field">
<xsl:if test="@name = $vRules/*/@name">
<newfield>
<xsl:apply-templates select="node()|@*"/>
</newfield>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
应用于原始提供的源XML文档时:
<document object="obj1">
<field name="A"/>
<field name="B"/>
<field name="C"/>
<field name="D"/>
<field name="E"/>
</document>
产生所需的结果:
<document object="obj1">
<newfield name="A"/>
<newfield name="B"/>
<newfield name="C"/>
</document>
注意“规则文档”仅在样式表中用于紧凑性。如果它是一个单独的文档,则只需使用实际href
调整所使用的document()
函数。
答案 1 :(得分:1)
也许我过于简单了,但是你的“规则文档”不能简单地成为XSLT的原因是什么?
答案 2 :(得分:1)
好吧,我明白为什么你想在一个简单的xml文件中使用规则,而不是在一个完整的xsl样式表中,但你只是跳过一个步骤。
您需要制作一个xsl样式表,将xml规则文档转换为xsl样式表,然后将其应用到源xml上。
诀窍在于命名空间,不会因应用的xsl规则和生成的xsl规则而混淆。
<?xml version="1.0" ?> <xsl:stylesheet xmlns="YOUR_NAMESPACE_HERE" xmlns:output="http://www.w3.org/1999/XSL/Transform" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:output method="xml" indent="yes" media-type="text/xsl" /> <xsl:template match="/"> <output:stylesheet version="2.0"> <xsl:apply-templates /> </output:stylesheet> </xsl:template> <xsl:template match="document[@object]"> <output:template match="document[@object='{@object}']"> <output:copy> <xsl:apply-templates /> </output:copy> </output:template> </xsl:template> <xsl:template match="field[@name]"> <output:if test="field[@name='{@name}']"> <output:copy-of select="field[@name='{@name}']" /> </output:if> </xsl:template> </xsl:stylesheet>
我假设您在规则和文档中使用相同的文档对象属性(这样更简单)。
因此,您可以通过上面的样式表运行规则文档。结果是一个新的xsl样式表,它完全按照您在xml规则文档中描述的那样执行。然后,将生成的样式表应用到源文档中,您应该得到预期的结果。