Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用xslt,根据第二个xml文档的内容转换一个xml文档_Xslt_Filtering - Fatal编程技术网

使用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

来调整所使用的功能,这很遗憾,因为这些是我收到的要求。:-)看看这个