2

我是使用 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 中) - 我在这里有几个选项 - 但我猜在 Bar 上填充 FooId 的方法将取决于整体方法?

(ps.为模糊的标题道歉 - 生病根据分辨率相应更新)

4

2 回答 2

1

我假设您想为输入中Foo的每个不同输出一个具有唯一 ID 的元素FooName。为此,您可以使用Muenchian 方法

首先,您将构建一个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>
于 2012-07-19T10:29:48.000 回答
0

它可以像这样简单,假设 aBarName在其对应的 之前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>
于 2012-07-19T11:50:57.793 回答