1

この XML 入力では、特定のセクションに要素を追加できません。

<Country>
  <info enum="CTRY" name="United Sates of America" total-states="50" />
  <info enum="ST" name="New York" population="8,244,910"/>
  <info enum="ST" name="Chicago" population="2,707,120"/>
  <info enum="CTRY" name="Germany" total-states="16"/>
  <info enum="ST" name="Berlin" population="3,469,910"/>
  <info enum="ST" name="Brandenburg" population="2,500,000"/>
</Country>

これが私のXSLです。

<xsl:template match="/">
  <Country>
    <xsl:for-each select="Country/info">
      <xsl:if test="@enum='CTRY'">
        <CountryInfo>
          <name>Country Name: <xsl:value-of select="@name"/></name>
          <districts><xsl:value-of select="@total-states"></xsl:value-of></districts>
          <xsl:for-each select="/Country/info">
            <xsl:if test="@enum='ST'">
              <state>
                <stateName>State Name: <xsl:value-of select="@name"/></stateName>
                <statePop>State Population: <xsl:value-of select="@population"/></statePop>
              </state>
            </xsl:if>
          </xsl:for-each>
        </CountryInfo>
      </xsl:if>
    </xsl:for-each>
  </Country>
</xsl:template>

問題は、すべての州が両方の国に表示されていることです。

生成しようとしている XML 出力は次のとおりです。

<Country>
  <CountryInfo>
    <name>Country Name: United Sates of America</name>
    <districts>50</districts>
    <state>
      <stateName>State Name: New York</stateName>
      <statePop>State Population: 8,244,910</statePop>
    </state>
    <state>
      <stateName>State Name: Chicago</stateName>
      <statePop>State Population: 2,707,120</statePop>
    </state>
  </CountryInfo>
  <CountryInfo>
    <name>Country Name: Germany</name>
    <districts>16</districts>
    <state>
      <stateName>State Name: Berlin</stateName>
      <statePop>State Population: 3,469,910</statePop>
    </state>
    <state>
      <stateName>State Name: Brandenburg</stateName>
      <statePop>State Population: 2,500,000</statePop>
    </state>
  </CountryInfo>
</Country>

XSLTでこれを達成することは可能ですか?

4

3 に答える 3

1

あなたのソースは XML の恐ろしい悪用です! そのようなゴミを設計して提供した人に、あなたは激しく不平を言うべきです.

単一のテンプレートでは、ソースに既に存在する要素を削除または展開する以外に何もできません。

この変換は必要なことを行うと思います。Countryルート要素をコピーしてその内容を処理することで機能します。2 番目のテンプレートは、出力要素の基礎を形成するの属性infoを持つすべての要素に一致します。enumCTRYCountryInfo

属性が の場合call-template、次の要素からの情報を挿入するためにを使用して、状態情報を再帰的に行う必要があります。infoenumST

ソース データの構造のため、この変換は非常に壊れやすく、予期しない要素があると壊れます。注意してください。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:strip-space elements="*"/>
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/Country">
    <xsl:copy>
      <xsl:apply-templates select="*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="info[@enum='CTRY']">
    <CountryInfo>
      <name>
        <xsl:text>Country name: </xsl:text>
        <xsl:value-of select="@name"/>
      </name>
      <districts>
        <xsl:value-of select="@total-states"/>
      </districts>
      <xsl:call-template name="state"/>
    </CountryInfo>
  </xsl:template>

  <xsl:template name="state">
    <xsl:param name="i" select="1"/>
    <xsl:if test="following-sibling::info[$i][@enum='ST']">
      <state>
        <stateName>
          <xsl:text>State Name: </xsl:text>
          <xsl:value-of select="following-sibling::info[$i]/@name"/>
        </stateName>
        <statePop>
          <xsl:text>State Population: </xsl:text> 
          <xsl:value-of select="following-sibling::info[$i]/@population"/>
        </statePop>
      </state>
      <xsl:call-template name="state">
        <xsl:with-param name="i" select="$i+1"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

出力

<?xml version="1.0" encoding="utf-8"?>
<Country>
   <CountryInfo>
      <name>Country name: United States of America</name>
      <districts>50</districts>
      <state>
         <stateName>State Name: New York</stateName>
         <statePop>State Population: 8,244,910</statePop>
      </state>
      <state>
         <stateName>State Name: Chicago</stateName>
         <statePop>State Population: 2,707,120</statePop>
      </state>
   </CountryInfo>
   <CountryInfo>
      <name>Country name: Germany</name>
      <districts>16</districts>
      <state>
         <stateName>State Name: Berlin</stateName>
         <statePop>State Population: 3,469,910</statePop>
      </state>
      <state>
         <stateName>State Name: Brandenburg</stateName>
         <statePop>State Population: 2,500,000</statePop>
      </state>
   </CountryInfo>
</Country>
于 2013-05-15T00:17:15.447 に答える