使用xslt,根据第二个xml文档的内容转换一个xml文档
我有一组文档,隐式定义了第二组对象的允许字段,这些对象必须转换为第三组文档( 使用哪种“规则”文档取决于要转换的文件的内容)例如使用xslt,根据第二个xml文档的内容转换一个xml文档,xslt,filtering,Xslt,Filtering,我有一组文档,隐式定义了第二组对象的允许字段,这些对象必须转换为第三组文档( 使用哪种“规则”文档取决于要转换的文件的内容)例如 是否可以使用xslt进行此转换 我明白了,所以我运气不好,或者我只是错误地看待这个问题?谢谢 也许我过于简单化了,但是您的“规则文档”不能简单地成为XSLT有什么原因吗?好吧,我可以理解为什么您希望将规则放在一个简单的xml文件中,而不是放在一个完整的xsl样式表中,但您只是跳过了一步 您需要制作一个xsl样式表,将xml规则文档转换为xsl样式表,然后应用于源x
是否可以使用xslt进行此转换
我明白了,所以我运气不好,或者我只是错误地看待这个问题?谢谢 也许我过于简单化了,但是您的“规则文档”不能简单地成为XSLT有什么原因吗?好吧,我可以理解为什么您希望将规则放在一个简单的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规则文档中描述的内容。然后将此结果样式表应用到源文档中,您应该会得到预期的结果。下面是一个简单的解决方案:
<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>
此转换:
<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>
产生所需的结果:
<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
来调整所使用的功能,这很遗憾,因为这些是我收到的要求。:-)看看这个