1

コンマで区切りたい情報エントリがいくつかあります。ただし、各エントリは空である可能性があり、最初に表示されるエントリが空の場合、コンマは表示されません。例えば:

名前、電話番号、住所、職業の 4 つの XSLT パラメータがあるとします。

そして私たちは持っています

  • 名前: ジョン
  • 電話番号:111-111-1111
  • 住所:空想通り
  • 職業: パン職人

次に、最終的な文字列は次のようになります。

ジョン、111-111-1111、イマジナリー ストリート、ベイカー

名前と電話番号のパラメーターが空または null の場合、最終的な文字列は次のようになります。

イマジナリー ストリート、ベイカー

電話番号のみが null または空の場合、最終的な文字列は次のようになります。

ジョン、イマジナリー・ストリート、ベイカー

C# のような言語では、次のようなコードを記述します。

foreach (EntryObject entry in entryList)
{
    if (firstEntry == true && entry.Type != EntryType.Age && entry.Type != EntryType.Sex)
    {
        finalString += entry.ValueString;
        firstEntry = false;
    }
    else if (firstEntry == false && entry.Type != EntryType.Age && entry.Type != EntryType.Sex)
    { 
        finalString += ", " + entry.ValueString;
    }
}
return finalString;

しかし、XSLT の変数はイミュータブルだと聞きました。XSLT でこの問題にどのようにアプローチすればよいですか?

編集: xml エントリは次のようになります。

<AddressBook>
    <PersonalInfo>
        <Age>33</Age>
        <Sex>Male</Sex>
        <Name>John</Name>
        <PhoneNumber></PhoneNumber>
        <Address>Imaginary Street</Address>
        <Occupation>Baker</Occupation>
    </PersonalInfo>
</AddressBook>

特定のエントリが空である可能性があることに注意してください。名前、電話番号、住所、職業のみを使用します。年齢と性別は無視してください。

4

2 に答える 2

2

空でない要素(string-length(.)>0または単にstring(.))のみに一致するXPath条件を使用してから、position()関数を使用して要素が最初であるかどうかを確認します。入力XML:

<root>
  <item>
    <name>John</name>
    <phoneNumber>111-111-1111</phoneNumber>
    <address>Imaginary street</address>
    <occupation>Baker</occupation>
  </item>
  <item>
    <name>Jane</name>
    <address>Another street</address>
    <occupation>Decorator</occupation>
  </item>
  <item>
    <address>Unknown</address>
  </item>
</root>

XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="item">
    <textItem>
      <xsl:for-each select="*[string(.)]">
        <xsl:if test="position()>1">
          <xsl:text>,</xsl:text>
        </xsl:if>
        <xsl:value-of select="."/>
      </xsl:for-each>
    </textItem>
  </xsl:template>

  <xsl:template match="text()">
  </xsl:template>

  <xsl:template match="root">
    <root>
      <xsl:apply-templates/>
    </root>
  </xsl:template>

</xsl:stylesheet>

ここで、最初のテンプレートは実際に作業を行うテンプレートであり、<xsl:template match="text()">一致しない要素に含まれるテキストを削除し(デフォルトでは、XSLTプロセッサーがそのようなテキストを出力にコピーします)<xsl:template match="root">、出力ドキュメントのルート要素を生成します。

結果:

<root>
  <textItem>John,111-111-1111,Imaginary street,Baker</textItem>
  <textItem>Jane,Another street,Decorator</textItem>
  <textItem>Unknown</textItem>
</root>

一部のフィールドのみに関心がある場合は、ユニオン演算子(|)を使用してフィールドを選択します。たとえば、上記の例で電話、住所、および職業のみが必要な場合は、XSLTを次のように変更します。

  <xsl:template match="item">
    <textItem>
      <xsl:for-each select="(phoneNumber|address|occupation)[string(.)]">
        <xsl:if test="position()>1">
          <xsl:text>,</xsl:text>
        </xsl:if>
        <xsl:value-of select="."/>
      </xsl:for-each>
    </textItem>
  </xsl:template>

  <xsl:template match="text()">
  </xsl:template>

  <xsl:template match="root">
    <root>
      <xsl:apply-templates/>
    </root>
  </xsl:template>

</xsl:stylesheet>
于 2012-11-26T21:31:32.227 に答える
2

「ブラックリストに載っている」要素名のリストをパラメーターとして受け入れる一般的なソリューションを次に示します。

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

 <xsl:param name="pIgnoreThese" select="' Age Sex '"/>

 <xsl:template match="PersonalInfo">
  <xsl:apply-templates select=
   "*[normalize-space()
    and
      not(contains($pIgnoreThese, concat(' ', name(), ' ')))
     ]"/>
   <xsl:text>&#xA;</xsl:text>
 </xsl:template>

 <xsl:template match="PersonalInfo/*">
  <xsl:if test="position() >1">, </xsl:if>
  <xsl:value-of select="."/>
 </xsl:template>
</xsl:stylesheet>

この変換が提供された XML ドキュメントに適用されると、次のようになります。

<AddressBook>
        <PersonalInfo>
            <Age>33</Age>
            <Sex>Male</Sex>
            <Name>John</Name>
            <PhoneNumber>111-111-1111</PhoneNumber>
            <Address>Imaginary Street</Address>
            <Occupation>Baker</Occupation>
        </PersonalInfo>
        <PersonalInfo>
            <Age>33</Age>
            <Sex>Male</Sex>
            <Name></Name>
            <PhoneNumber></PhoneNumber>
            <Address>Imaginary Street</Address>
            <Occupation>Baker</Occupation>
        </PersonalInfo>
        <PersonalInfo>
            <Age>33</Age>
            <Sex>Male</Sex>
            <Name>John</Name>
            <PhoneNumber></PhoneNumber>
            <Address>Imaginary Street</Address>
            <Occupation>Baker</Occupation>
        </PersonalInfo>
</AddressBook>

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

John, 111-111-1111, Imaginary Street, Baker
Imaginary Street, Baker
John, Imaginary Street, Baker
于 2012-11-27T04:59:03.877 に答える