Функция xsl generate-id () дважды возвращает один и тот же идентификатор для разных узлов - PullRequest
0 голосов
/ 14 февраля 2012

У меня есть входной XML для преобразования, как;

<?xml version="1.0" encoding="UTF-8" ?>
<AssetcustomerCollection xmlns="http://xmlns.oracle.com/pcbpel/adapter/db/top/somens">
  <Assetcustomer xmlns="">
   ....
  </Assetcustomer>
  <Assetcustomer xmlns="">
    <accountklantid>000000123456789</accountklantid>
    <accountrowid>1-W8HQ1J</accountrowid>
    <adrestypeaccnt/>
    <adrestypecon/>
    <assetbankcode>1173</assetbankcode>
    <assetnumber>0000001234</assetnumber>
    <assetprodcode>1200</assetprodcode>
    <assetproduct>Overeenkomst Rekening-courant</assetproduct>
    <assetproductlocatie>00</assetproductlocatie>
    <assetstatus>Actief</assetstatus>
    <assetsubstatus>Lopende rekening</assetsubstatus>
    <assettypecode>0010</assettypecode>
    <contactklantid/>
    <contactrowid/>
    <primairaccount>Y</primairaccount>
    <primaircontact>N</primaircontact>
    <reltypeaccnt>Hoofdcontractant</reltypeaccnt>
    <reltypecon/>
    <rowidasset>1-X3XBMO</rowidasset>
    <rowidassetaccnt>1-X3XBMQ</rowidassetaccnt>
    <rowidassetcon/>
    <tnsidaccnt/>
    <tnsidcon/>
  </Assetcustomer>
  <Assetcustomer xmlns="">
   ....
  </Assetcustomer>
  <Assetcustomer xmlns="">
    <accountklantid/>
    <accountrowid/>
    <adrestypeaccnt/>
    <adrestypecon/>
    <assetbankcode>1173</assetbankcode>
    <assetnumber>0000004321</assetnumber>
    <assetprodcode>1201</assetprodcode>
    <assetproduct>WereldPas (Zakelijk)</assetproduct>
    <assetproductlocatie>00</assetproductlocatie>
    <assetstatus>Actief</assetstatus>
    <assetsubstatus>Lopende rekening</assetsubstatus>
    <assettypecode>0003</assettypecode>
    <contactklantid>000000987654321</contactklantid>
    <contactrowid>1-X17PLM</contactrowid>
    <primairaccount>N</primairaccount>
    <primaircontact>Y</primaircontact>
    <reltypeaccnt/>
    <reltypecon>Pasverantwoordelijke</reltypecon>
    <rowidasset>1-X3XBN0</rowidasset>
    <rowidassetaccnt/>
    <rowidassetcon>1-X3XBNE</rowidassetcon>
    <tnsidaccnt/>
    <tnsidcon/>
  </Assetcustomer>
  <Assetcustomer xmlns="">
   ....
  </Assetcustomer>
</AssetcustomerCollection>

При преобразовании этого входного XML я получил неожиданный вывод (15 из 16 входных узлов Assetcustomer были преобразованы) Теперь я нашел причину, но не могу объяснить, почему это происходит;

Следующее преобразование дважды возвращает один и тот же идентификатор;

<xsl:element name="A">
  <xsl:value-of select="generate-id(key('AssetRowIDs',/ns0:AssetcustomerCollection/Assetcustomer[rowidasset = '1-X3XBMO']/*)[1])"/>
</xsl:element>
<xsl:element name="B">
  <xsl:value-of select="generate-id(key('AssetRowIDs',/ns0:AssetcustomerCollection/Assetcustomer[rowidasset = '1-X3XBN0']/*)[1])"/>
</xsl:element>


<A>N10211</A>
<B>N10211</B>

Хотя сгенерированный идентификатор для любого другого узла с другим rowidasset отличается.

Есть какие-нибудь идеи, прежде чем я начну вырывать свои волосы?

Peter

Я не знаю точно, почему, но меняется

<xsl:key name="AssetRowIDs" match="Assetcustomer" use="rowidasset"/>

в

<xsl:key name="AssetRowIDs" match="Assetcustomer" use="concat('-',rowidasset,'-')"/>

и

<xsl:for-each select="/ns0:AssetcustomerCollection/Assetcustomer[generate-id() = generate-id(key('AssetRowIDs',rowidasset)[1])]">

в

<xsl:for-each select="/ns0:AssetcustomerCollection/Assetcustomer[generate-id() = generate-id(key('AssetRowIDs',concat('-',rowidasset,'-'))[1])]">

Кажется, генерируется уникальный идентификатор для каждого узла, но я все равно не могу понять причину этого.

1 Ответ

0 голосов
/ 14 февраля 2012

Проверить пространство имен? Если префикс ns0 связан с неверным URI пространства имен, ваш запрос в обоих случаях даст пустой набор результатов. Вместе с тем же первым аргументом для ключа, который, я полагаю, приведет к тому же вызову key() и, следовательно, к тому же идентификатору.

Также я не думаю, что функция key() делает то, что вы думаете: http://www.w3schools.com/xsl/func_key.asp

В любом случае вы можете применить generate-id() непосредственно к набору узлов, для которого вы хотите вычислить идентификатор.

...