2012-07-19 116 views
2

我是使用XSLT的新手。我的要求最好通过代码表达。我正在寻找关于是否可以通过XLST达到我的要求的建议。我并不是要求人们为我写代码 - 尽管代码建议也值得赞赏。我正在寻找指针,例如“我需要链接多个转换”。我正在使用XSLT v1.0。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元素最先在Bar元素之前。

我并不过分担心生成Foo Id(即在上面的示例100中) - 我在这里有几个选项 - 但我猜想在条上填充FooId的方法将取决于总体方法?

(PS道歉模糊的标题 - 相应地基于分辨率生病更新)

+0

我认为你是需要更多的信息来提供一些有用的东西。写一些能够提供你想要的东西并且给你想要的东西很容易,但是它会留下问题,是否有多个输入,多个foos,多个条。 FooId的重要性是什么?为什么它是一个元素而不是一个属性?等 – Woody 2012-07-19 10:24:58

回答

1

我假设你要输出一个唯一的ID一Foo元素在输入每个不同FooName。为此,您可以使用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> 
+0

谢谢Jukka。我已经测试过了,它确实有效!感谢NB提供的支持文本/链接 - 让v清楚发生了什么。 – Damo 2012-07-19 13:07:49

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> 
+0

谢谢你的帖子Dimitre。它有用2比较这种方法Jukka的职位。 – Damo 2012-07-19 13:11:19

+0

@Damo:Jukka作出了一些猜测,得出结论认为需要分组。这可能是对还是错。我不做任何猜测 - 只是使用问题中提供的信息。 Jukka提出的任何“BarName”的狂野猜测都应该绑定到第一个唯一的“FooName” - 我认为这很可能是一个错误的假设。如果您的数据更加具体,您会得到更准确的答案,而不仅仅是真实数据的基本草图/投影。 – 2012-07-19 13:55:48