我是使用XSLT的新手。我的要求最好通过代码表达。我正在寻找关于是否可以通过XLST实现我的要求的建议。我不是要求人们为我编写代码 - 尽管代码建议也会受到赞赏。我正在寻找指针,例如“我需要链接多个变换”。我正在使用XSLT v1.0。
我有输入XML;
<Input>
<BarId>123</BarId>
<BarName>myname</BarName>
<FooName>dummy</FooName>
</Input>
...并且需要创建输出;
<Out>
<Foos>
<Foo>
<Id>100</Id>
<Name>dummy</Name>
</Foo>
</Foos>
<Bars>
<Bar>
<Id>123</Id>
<Name>myname</Name>
<FooId>100</FooId>
</Bar>
</Bars>
</Out>
关键点:
创建Foo元素是我需要帮助的部分。
Foo元素最多位于Bar元素之前。
我并不过分关注生成Foo Id(即上面的示例100) - 我在这里有几个选项 - 但我想在条形图上填充FooId的方法将取决于整体方法?
(ps。对于模糊标题道歉 - 根据决议进行相应的更新)
答案 0 :(得分:1)
我假设您要输入一个Foo
元素,其中包含输入中每个不同FooName
的唯一ID。为此,您可以使用Muenchian method:
首先,您需要构建一个xsl:key
,您可以使用该内容快速检索FooName
元素。
<xsl:key name="FooNames" match="FooName" use="."/>
使用此键,您可以只处理每个FooName的第一个实例,从而获得一个不同的列表。在这里,您可以使用generate-id()
函数来比较节点的身份。
<xsl:apply-templates select="//FooName
[generate-id() =
generate-id(key('FooNames', .)[1])]"/>
为了生成标识符,如果您不关心生成的标识符可能因运行而异,则可以再次使用generate-id()
函数。
全部放在一起:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="FooNames" match="FooName" use="."/>
<xsl:template match="/">
<Out>
<Foos>
<xsl:apply-templates select="//FooName[generate-id() =
generate-id(key('FooNames', .)[1])]"/>
</Foos>
<Bars>
<xsl:apply-templates select="//Input"/>
</Bars>
</Out>
</xsl:template>
<xsl:template match="FooName">
<Foo>
<Id><xsl:value-of select="generate-id()"/></Id>
<Name><xsl:value-of select="."/></Name>
</Foo>
</xsl:template>
<xsl:template match="Input">
<Bar>
<Id><xsl:value-of select="BarId"/></Id>
<Name><xsl:value-of select="BarName"/></Name>
<FooId>
<xsl:value-of select="generate-id(key('FooNames', FooName)[1])"/>
</FooId>
</Bar>
</xsl:template>
</xsl:stylesheet>
使用以下示例输入:
<Inputs>
<Input>
<BarId>123</BarId>
<BarName>myname</BarName>
<FooName>dummy</FooName>
</Input>
<Input>
<BarId>124</BarId>
<BarName>anothername</BarName>
<FooName>dummy</FooName>
</Input>
<Input>
<BarId>125</BarId>
<BarName>yetanothername</BarName>
<FooName>dummy-two</FooName>
</Input>
</Inputs>
它将产生输出:
<Out>
<Foos>
<Foo>
<Id>id213296</Id>
<Name>dummy</Name>
</Foo>
<Foo>
<Id>id214097</Id>
<Name>dummy-two</Name>
</Foo>
</Foos>
<Bars>
<Bar>
<Id>123</Id>
<Name>myname</Name>
<FooId>id213296</FooId>
</Bar>
<Bar>
<Id>124</Id>
<Name>anothername</Name>
<FooId>id213296</FooId>
</Bar>
<Bar>
<Id>125</Id>
<Name>yetanothername</Name>
<FooId>id214097</FooId>
</Bar>
</Bars>
</Out>
答案 1 :(得分:0)
可以这么简单,假设BarName
位于其对应的FooName
之前:
<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:template match="/*">
<Out>
<Foos>
<xsl:apply-templates select="FooName"/>
</Foos>
<Bars>
<xsl:apply-templates select="BarName"/>
</Bars>
</Out>
</xsl:template>
<xsl:template match="FooName">
<Foo>
<Id><xsl:call-template name="makeFooId"/></Id>
<Name><xsl:value-of select="."/></Name>
</Foo>
</xsl:template>
<xsl:template match="BarName">
<Bar>
<Id><xsl:value-of select="preceding-sibling::BarId[1]"/></Id>
<Name><xsl:value-of select="."/></Name>
<FooId>
<xsl:call-template name="makeFooId">
<xsl:with-param name="pFoo" select="following-sibling::FooName[1]"/>
</xsl:call-template>
</FooId>
</Bar>
</xsl:template>
<xsl:template name="makeFooId">
<xsl:param name="pFoo" select="."/>
<!-- Replace the following line with your id - generating code -->
<xsl:text>100</xsl:text>
</xsl:template>
</xsl:stylesheet>
将此转换应用于提供的XML文档时:
<Input>
<BarId>123</BarId>
<BarName>myname</BarName>
<FooName>dummy</FooName>
</Input>
产生了想要的正确结果:
<Out>
<Foos>
<Foo>
<Id>100</Id>
<Name>dummy</Name>
</Foo>
</Foos>
<Bars>
<Bar>
<Id>123</Id>
<Name>myname</Name>
<FooId>100</FooId>
</Bar>
</Bars>
</Out>