-1
<Rootnode>
    <Properties Attribute ="xxx">
        <Type>1</Type>
        <Size>10</Size>
    </Properties>
    <Other>
        <blah>h</blah>
    </Other>
    <Other2>
        <blah>h</blah>
    </Other2>
    <Properties Attribute ="xxx">
        <xType>5</xType>
        <xSize>10</xSize>
    </Properties>
    <Items>
       <Item4>8</Item4>
    </Items>
    <Items>
       <Item6>8</Item6>
    </Items>
    <Properties Attribute ="xxx">
        <zType>1</zType>
        <zSize>10</zSize>
    </Properties>
    <Items place="UK">
       <Item1>8</Item1>
    </Items>
 </Rootnode>

今私が欲しいのは、プロパティとアイテムのみを含めることです。属性が同じ名前と値である場合は、プロパティとアイテムのグループを結合し、属性に基づいてプロパティとアイテムの両方をソートし、両方の子ノードをアルファベット順にソートすることをお勧めします。これまでのところ、私は空白に達しました;(

必要な出力は、ABach が示したとおりです。言い忘れたことの 1 つは、各プロパティまたは項目に他の属性が存在する可能性があることと、並べ替えたい属性の名前を知っていることです。簡単に修正できること。

つまり、必要な出力

<?xml version="1.0"?>
<Rootnode>
  <Properties Attribute="xxx">
    <Size>10</Size>
    <Type>1</Type>
    <xSize>10</xSize>
    <xType>5</xType>
    <zSize>10</zSize>
    <zType>1</zType>
  </Properties>
  <Items>
    <Item4>8</Item4>
    <Item6>8</Item6>
  </Items>
  <Items place="UK">
    <Item1>8</Item1>
  </Items>
</Rootnode>

そして、これまでの努力が不足していたことをお詫びします...私は正しい混乱に陥り、それがあまり役立つとは思いませんでした...私はこのことにかなり慣れていません:)

4

2 に答える 2

2

@LarsHがすでに指摘しているように、期待される出力XMLを表示しないことで、本当に必要なものを推測する必要があります。そうは言っても、これがXSLT1.0ソリューションでの私の試みです。

このXSLTの場合:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
  <xsl:output omit-xml-declaration="no" indent="yes" />
  <xsl:strip-space elements="*" />

  <xsl:key
    name="PropertiesByAttributeNameVal"
    match="Properties"
    use="concat(name(@*[1]), '+', @*[1])" />

  <xsl:key
    name="ItemsByAttributeNameVal" 
    match="Items"
    use="concat(name(@*[1]), '+', @*[1])" />

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

  <xsl:template match="Rootnode">
    <Rootnode>
      <xsl:apply-templates 
        select="Properties[
          generate-id() = 
          generate-id(key(
            'PropertiesByAttributeNameVal',
             concat(name(@*[1]), '+', @*[1]))[1])]">
        <xsl:with-param name="pKeyName"
          select="'PropertiesByAttributeNameVal'" />
        <xsl:sort select="concat(name(@*[1]), '+', @*[1])" />
      </xsl:apply-templates>
      <xsl:apply-templates
        select="Items[
          generate-id() = 
          generate-id(key(
            'ItemsByAttributeNameVal',
            concat(name(@*[1]), '+', @*[1]))[1])]">
        <xsl:with-param name="pKeyName"
          select="'ItemsByAttributeNameVal'" />
        <xsl:sort select="concat(name(@*[1]), '+', @*[1])" />
      </xsl:apply-templates>
    </Rootnode>
  </xsl:template>

  <xsl:template match="Properties|Items">
    <xsl:param name="pKeyName" />
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:apply-templates
        select="key($pKeyName, concat(name(@*[1]), '+', @*[1]))/*">
        <xsl:sort select="name()" />
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

...提供されたXMLに対する実行:

<Rootnode>
  <Properties Attribute="xxx">
    <Type>1</Type>
    <Size>10</Size>
  </Properties>
  <Other>
    <blah>h</blah>
  </Other>
  <Other2>
    <blah>h</blah>
  </Other2>
  <Properties Attribute="xxx">
    <xType>5</xType>
    <xSize>10</xSize>
  </Properties>
  <Items>
    <Item4>8</Item4>
  </Items>
  <Items>
    <Item6>8</Item6>
  </Items>
  <Properties Attribute="xxx">
    <zType>1</zType>
    <zSize>10</zSize>
  </Properties>
  <Items place="UK">
    <Item1>8</Item1>
  </Items>
</Rootnode>

...私が推測するのは、正しい出力XMLが生成されることです。

<?xml version="1.0"?>
<Rootnode>
  <Properties Attribute="xxx">
    <Size>10</Size>
    <Type>1</Type>
    <xSize>10</xSize>
    <xType>5</xType>
    <zSize>10</zSize>
    <zType>1</zType>
  </Properties>
  <Items>
    <Item4>8</Item4>
    <Item6>8</Item6>
  </Items>
  <Items place="UK">
    <Item1>8</Item1>
  </Items>
</Rootnode>

この同じXSLTがわずかに変更されたXMLドキュメント(より多くのグループ化などがある)に対して実行される場合は、次の点に注意してください。

<?xml version="1.0" encoding="utf-8"?>
<Rootnode>
  <Properties Attribute="xxx">
    <Type>1</Type>
    <Size>10</Size>
  </Properties>
  <Other>
    <blah>h</blah>
  </Other>
  <Other2>
    <blah>h</blah>
  </Other2>
  <Properties Attribute="yyy">
    <xType>5</xType>
    <xSize>10</xSize>
  </Properties>
  <Items>
    <Item4>8</Item4>
  </Items>
  <Items place="US">
    <Item9>8</Item9>
  </Items>
  <Items>
    <Item1>8</Item1>
  </Items>
  <Properties Attribute2="xxx">
    <zType>1</zType>
    <zSize>10</zSize>
  </Properties>
  <Properties Attribute="xxx">
    <elephantType>5</elephantType>
    <elephantSize>15</elephantSize>
  </Properties>
  <Items place="UK">
    <Item1>8</Item1>
  </Items>
</Rootnode>

...繰り返しますが、正しい答えが生成されると私は思います:

<?xml version="1.0"?>
<Rootnode>
  <Properties Attribute="xxx">
    <Size>10</Size>
    <Type>1</Type>
    <elephantSize>15</elephantSize>
    <elephantType>5</elephantType>
  </Properties>
  <Properties Attribute="yyy">
    <xSize>10</xSize>
    <xType>5</xType>
  </Properties>
  <Properties Attribute2="xxx">
    <zSize>10</zSize>
    <zType>1</zType>
  </Properties>
  <Items>
    <Item1>8</Item1>
    <Item4>8</Item4>
  </Items>
  <Items place="UK">
    <Item1>8</Item1>
  </Items>
  <Items place="US">
    <Item9>8</Item9>
  </Items>
</Rootnode>

仮定:

  • それぞれ<Properties><Items>要素には1つの属性しかなく、それがグループ化の決定要因になるはずだと思います。
  • 上記が当てはまらない場合は、少なくとも、その要素の最初の属性はグループ化の限定詞である必要があると思います。

説明:

  1. これはXSLT1.0ソリューションでMuenchian Groupingあるため、一意のセレクターの下でノードと属性をグループ化する日の順序です。したがって、2つのキーを定義します。1つは<Properties>要素用、もう1つは<Items>要素用です。

  2. 最初のテンプレートはIdentity Transform-その仕事は、すべてのノードと属性をソースドキュメントから結果ドキュメントにそのまま出力することです。

  3. 2番目のテンプレートは<Rootnode>要素と一致します。それぞれのキーに最初に表示される要素<Properties>と要素にのみテンプレートを適用するように指示されています。<Items>これには、(最初​​の属性の名前と値に基づいて)一意の要素のみを処理するという意図された効果があります。

    要素を指定する<xsl:apply-templates>と、どちらの場合も、同じ属性名と値の組み合わせで結果を並べ替えるように指示されることに注意してください。

    <xsl:apply-templates>各要素には(を介して)パラメータが与えられていることに注意してください<xsl:with-param>。ご覧のとおり、要素<Properties><Items>要素の両方を処理するコードはほぼ同じです。唯一の違いは、結果を取得するためのキーです。このため、そのロジックを3番目のテンプレートに統合し、このパラメーターを介して変動性を考慮することにしました。

  4. 3番目のテンプレートは<Properties><Items>要素の両方に一致します。それぞれについて、元のノードがコピーされます(その属性も同様です)。最後に、テンプレートがこの要素のすべての子要素に適用されます([今回は、子要素自体の名前に基づいて]適切な並べ替えが行われます)。

于 2012-11-12T20:29:41.030 に答える
1

何もないよりも、すでに何かを持っている方が助けを受ける可能性が高くなります。match="Properties | Items"開始するには、コンテンツが一致した要素をコピーするだけのプロパティと項目 ( ) に一致するテンプレートを作成します: <xsl:copy-of select="." />

これにより、表示する実用的なコードが得られます。

私が提案する次のステップは、目的の出力のサンプルと、XSLT コードによって得られる実際の出力を投稿することです。

これにより、人々があなたの質問に答える際に橋渡しできるギャップがはるかに小さくなります。

于 2012-11-12T16:22:50.247 に答える