我有一组隐式定义允许的字段的第二组必须被转变为第三组文档对象的文档( 其中“规则”的文件使用取决于的文件待转化的含量)例如

<!-- 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做这种转变?

我看到“没有构建XPath表达式的方式在XSLT(例如,变量引用)在运行时。“所以我的运气,还是我只是在看这个问题是否有误?谢谢!

有帮助吗?

解决方案

<强>下面是一个简单的解决方案

:此转化

<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() 用于将需要的功能与实际href进行调整。

其他提示

也许我过于简单化,但有一个原因,你的“规则文档”不能简单地将一个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>

我认为你会使用相同的文件对象属性中的规则,并在文件本身(这是更简单IMO)。

所以,你通过样式表上面运行你的规则文件。其结果是一个新的XSL样式表不正是你的XML规则文档中描述。然后,您将此导致样式表到您的源文件,你应该得到你所期望的结果。

scroll top