3

特定の名前のすべてのノードに、それらのノードで使用できるすべての要素のスーパーセットが含まれるようにXMLを変換したいと思います。

たとえば、これが入力xmlです。このxmlでは、グループに1つ以上のアイテムノードを含めることができます。発信者は、そのグループで利用可能なアイテムのみを渡します。

<group>
   <item>
       <name> item1 </name>
       <value> 10 </value>
   </item>
</group>
<group>
    <item>
       <name> item2 </name>
       <value> 20 </value>
     </item>
</group>

要件は、それを以下に示すものに変換することです。ここで、すべてのグループのアイテムノードは各グループの一部である必要があります。ただし、その項目がそのグループの入力で使用できない場合は、値0を入力する必要があります。

<group>
   <item>
       <name> item1 </name>
       <value> 10 </value>
   </item>
   <item>
       <name> item2 </name>
       <value> 0 </value>
   </item>
</group>
<group>
     <item>
       <name> item1 </name>
       <value> 0 </value>
     </item>    
    <item>
       <name> item2 </name>
       <value> 20 </value>
     </item>
</group>

XSLTを使用してこれを実現する方法を教えてください。

ありがとう

4

2 に答える 2

1

これが私がそれを行う方法です(指定しなかったため、XSLT 2.0で)...

XML 入力(整形式になるようにラップされ<groups>ています)

<groups>
    <group>
        <item>
            <name> item1 </name>
            <value> 10 </value>
        </item>
    </group>
    <group>
        <item>
            <name> item2 </name>
            <value> 20 </value>
        </item>
    </group>
</groups>

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:variable name="names" select="distinct-values(/*/group/item/name)"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="group">
        <xsl:variable name="currentItems" select="item/name"/>
        <xsl:variable name="items" as="node()*">
            <xsl:apply-templates select="item"/>
            <xsl:for-each select="$names[not(. = current()/item/name)]">
                <item>
                    <name><xsl:value-of select="."/></name>
                    <value> 0 </value>
                </item>
            </xsl:for-each>         
        </xsl:variable>
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:perform-sort select="$items">
                <xsl:sort select="name"/>
            </xsl:perform-sort>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

XML 出力

<groups>
   <group>
      <item>
         <name> item1 </name>
         <value> 10 </value>
      </item>
      <item>
         <name> item2 </name>
         <value> 0 </value>
      </item>
   </group>
   <group>
      <item>
         <name> item1 </name>
         <value> 0 </value>
      </item>
      <item>
         <name> item2 </name>
         <value> 20 </value>
      </item>
   </group>
</groups>
于 2012-12-02T04:06:49.017 に答える
0

これは、XSLT1.0とXSLT2.0の両方のソリューションです。

<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:variable name="vGroupContent" select="/*/group/node()"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="group">
  <group>
   <xsl:apply-templates select=
    "node()|@*|$vGroupContent[not(name = current()/item/name)]">
    <xsl:with-param name="pGroup" select="."/>
     <xsl:sort select="name"/>
   </xsl:apply-templates>
  </group>
 </xsl:template>

 <xsl:template match="item">
  <xsl:param name="pGroup"/>
  <item>
    <xsl:apply-templates select="name"/>
    <value> <xsl:value-of select=
    "value/text()[generate-id($pGroup) = generate-id(../../..)]"/>

    <xsl:if test=
     "value/text()[not(generate-id($pGroup) = generate-id(../../..))]"> 0 </xsl:if>
    </value>
  </item>
 </xsl:template>
</xsl:stylesheet>

この変換が次のXMLドキュメントに適用される場合:

<t>
    <group>
        <item>
            <name> item1 </name>
            <value> 10 </value>
        </item>
    </group>
    <group>
        <item>
            <name> item2 </name>
            <value> 20 </value>
        </item>
    </group>
</t>

必要な正しい結果が生成されます。

<t>
   <group>
      <item>
         <name> item1 </name>
         <value> 10 </value>
      </item>
      <item>
         <name> item2 </name>
         <value> 0 </value>
      </item>
   </group>
   <group>
      <item>
         <name> item1 </name>
         <value> 0 </value>
      </item>
      <item>
         <name> item2 </name>
         <value> 20 </value>
      </item>
   </group>
</t>
于 2012-12-02T03:53:42.230 に答える