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

I am assuming you want to output a Foo element with a unique ID for each distinct FooName in the input. For this, you could use the Muenchian method:

First you'd build a xsl:key using which you can quickly retrieve FooName elements by their content.

<xsl:key name="FooNames" match="FooName" use="."/>

Using this key, you can then process only the first instance of each FooName, thus getting a distinct list. Here you can make use of the generate-id() function for comparing nodes for identity.

<xsl:apply-templates select="//FooName
                             [generate-id() = 
                              generate-id(key('FooNames', .)[1])]"/>

For generating the identifiers, if you don't care that the generated identifiers may vary from run to run, you can again use the generate-id() function.

Putting it all together:

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

With the following sample input:

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

It will yield the output:

<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

BarNameaが対応するの前にあると仮定すると、次のように単純になります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 に答える