1

このxmlフラグメントを変換したい

<Sets>
    <Set id="category.product.typeA.item1"/>
    <Set id="category.product.typeB.item2"/>
    <Set id="category.product.typeC.item3"/>
    <Set id="category.product.typeA.item2"/>
    <Set id="category.product.typeA.item3"/>
    <Set id="category.service.typeA.item1"/>
    <Set id="category.service.typeA.item2"/>
    <Set id="category.product.typeA.item4"/>
    <Set id="category.product.typeA.item5"/>
</Sets>

次の xml フラグメントに変換します。

<Category id="category.product">
    <Group id="category.product.typeA">
        <Set id="category.product.typeA.item1"/>
        <Set id="category.product.typeA.item2"/>
        <Set id="category.product.typeA.item3"/>
        <Set id="category.product.typeA.item4"/>
        <Set id="category.product.typeA.item5"/>        
    </Group>
    <Group id="category.product.typeB"> 
        <Set id="category.product.typeB.item2"/>
    </Group>
    <Group id="category.product.typeC"> 
        <Set id="category.product.typeC.item3"/>
    </Group>
</Category>
<Category id="category.service">
    <Group id="category.service.typeA">
        <Set id="category.service.typeA.item1"/>
        <Set id="category.service.typeA.item2"/>
    </Group>
</Category>

基本的に、属性値に基づいて要素を別々のグループに入れたいと思います。

したがって、一致する属性値を持つ要素: category.product.typeA.* は 1 つのグループに配置する必要があります category.product.typeB.* は別のグループに配置する必要があります

属性の値が category.product.* と一致する場合、そのグループは 1 つのカテゴリに分類され、属性の値が category.service.* と一致する場合は別のカテゴリに分類されます。

「starts-with」と「for-each-group」で努力しましたが、要素のグループ化と属性のワイルドカード マッチングの両方をまとめることができず、助けていただければ幸いです。

4

1 に答える 1

1

これが私の提案です:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:mf="http://example.com/mf"
  exclude-result-prefixes="xs mf"
  version="2.0">

<xsl:output indent="yes"/>

<xsl:template match="Sets">
  <xsl:for-each-group select="Set" group-by="string-join(tokenize(@id, '\.')[position() lt 3], '.')">
    <Category id="{current-grouping-key()}">
      <xsl:for-each-group select="current-group()" group-by="string-join(tokenize(@id, '\.')[position() lt 4], '.')">
        <Group id="{current-grouping-key()}">
          <xsl:copy-of select="current-group()"/>
        </Group>
      </xsl:for-each-group>
    </Category>
  </xsl:for-each-group>
</xsl:template>

</xsl:stylesheet>

そのスタイルシートをSaxon 9.4で入力に適用すると、必要な結果が得られます

<Category id="category.product">
   <Group id="category.product.typeA">
      <Set id="category.product.typeA.item1"/>
      <Set id="category.product.typeA.item2"/>
      <Set id="category.product.typeA.item3"/>
      <Set id="category.product.typeA.item4"/>
      <Set id="category.product.typeA.item5"/>
   </Group>
   <Group id="category.product.typeB">
      <Set id="category.product.typeB.item2"/>
   </Group>
   <Group id="category.product.typeC">
      <Set id="category.product.typeC.item3"/>
   </Group>
</Category>
<Category id="category.service">
   <Group id="category.service.typeA">
      <Set id="category.service.typeA.item1"/>
      <Set id="category.service.typeA.item2"/>
   </Group>
</Category>
于 2012-12-20T10:09:47.833 に答える