使用XSLT基于XML中的另一个属性值创建新属性



我刚开始学习xslt。我需要这个输入xml文件:

<response>
<type>Some type</type>
<attribute name="First"/>
<attribute name="Second"/>
...
<attribute name="nth"/>
<attribute name="start_action">
<ActionValue>
<entryMap name="entryvalue1">
<action>
<type>some app statement</type>
<attribute name="type" value="apps jump" />
</action>
</entryMap>
<entryMap name="entryvalue2">
<action>
<type>some phase statement</type>
<attribute name="type" value="phases2" />
</action>
</entryMap>
<entryMap name="entryvalue3">
<action>
<type>some phase statement</type>
<attribute name="type" value="phases3" />
</action>
</entryMap>
<entryMap name="...">
<action>
<type>...</type>
<attribute name="type" value="..." />
</action>
</entryMap>
</ActionValue>
</attribute>
</response>

(…用于概括输入xml,以便可以添加更多的阶段和应用程序部分。(

要转换为此输出xml文件:

<response>
<type>Some type</type>
<attribute name="First"/>
<attribute name="Second"/>
...
<attribute name="nth"/>
<attribute name="start_action">
<ActionValue>
<entryMap name="entryvalue1">
<action>
<type>some app statement</type>
<attribute name="type" value="apps jump" />
<attribute name="app_name" value="entryvalue1" />
</action>
</entryMap>
<entryMap name="entryvalue2">
<action>
<type>some phase statement</type>
<attribute name="type" value="phases2" />
<attribute name="phase_name" value="entryvalue2" />
</action>
</entryMap>
<entryMap name="entryvalue3">
<action>
<type>some phase statement</type>
<attribute name="type" value="phases3" />
<attribute name="phase_name" value="entryvalue3" />
</action>
</entryMap>
<entryMap name="...">
<action>
<type>...</type>
<attribute name="type" value="..." />
<attribute name="..." value="..." />
</action>
</entryMap>
</ActionValue>
</attribute>
</response>

因此,在输入文件中,当我有<attribute name="type" value="apps jump" />时,我需要在<attribute name="type" value="apps jump" />之后添加<attribute name="app_name" value="entryvalue1" />。并且当我具有CCD_ 4或CCD_"在CCD_ 6中,而不是"strong>";应用程序跳转"则我需要在具有type元素的属性之后添加<attribute name="phase_name" value="entryvalue2" />,即对于第二种情况<attribute name="type" value="phases2" />。此外,<attribute name="app_name" value="entryvalue1" /><attribute name="phase_name" value="entryvalue2" />中的值,依此类推,保持其相应的entryMap名称值的值。

在这个例子中,我有一个应用程序和两个阶段部分,首先定义了应用程序,然后定义了两个阶段,但这并不是固定的。我可以在输入xml的任何位置都有多个应用程序和阶段部分,但处于同一级别。例如,我可以有2个应用程序,然后是3个阶段,然后是6个应用程序和1个阶段。因此,我正在尝试创建一个通用xslt,它将适用于任何数量的应用程序和阶段部分。

我现在拥有的当前示例XSLT是:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- Identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="action">
<xsl:copy>
<xsl:copy-of select="*"/>
<attribute name="phase_name" value="{../@name}"/>
<attribute name="app_name" value="{../@name}"/>
</xsl:copy>
</xsl:template>
<xsl:template match="action">
<xsl:for-each select="attribute">
<xsl:if test="@name='phase_name'">
<xsl:value-of select="@value"/>
</xsl:if>
<xsl:if test="@name='app_name'">
<xsl:value-of select="@value"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

我无法将我的逻辑合并到XSLT中。如果有人能帮我解决这个问题,我将不胜感激。提前谢谢。

您已经将问题描述编写为一组条件操作规则,这很好:您需要做的是将这些规则直接转换为模板规则。例如:

因此,在输入文件中,当我有<attribute name="type" value="apps jump" />时,我需要在<attribute name="type" value="apps jump" />之后添加<attribute name="app_name" value="entryvalue1" />

这就是

<xsl:template match="attribute[@name='type'][@value='apps jump']">
<xsl:copy/>
<attribute name="app_name" value="{ancestor::entryMap/@name}"/>
</xsl:template

当我有<attribute name="type" value="phases2" />或CCD_ 15或值为"0"的任意值"在里面CCD_ 16;应用程序跳转";那么我需要添加<attribute name="phase_name" value="entryvalue2" />具有类型元素的属性,即对于第二种情况CCD_ 18。

这个变成了类似的东西

<xsl:template match="attribute[@name='type'][@value!='apps jump']">
<xsl:copy/>
<attribute name="app_name" value="{ancestor::entryMap/@name}"/>
</xsl:template>

但我显然还没有完全理解你的逻辑,因为这些规则是相同的。我不确定您的规则中的entryMap1等是文字值还是源文档中的值。

最新更新