2

私はこれらのことを別々に行っているいくつかの投稿をレビューしましたが、まだそれらをすべてうまく組み合わせるには至っていません。

私はこの構造に似た入力を持っています:

 <Response>
    <Confirmation>Success</Confirmation>
    <SecondResponse>
       <InquiryResponse>
          <ID>99999</ID>
          <Confirmation>Success</Confirmation>
          <Exception/>
          <!-- The following structure repeats a varying amount of times -->
          <DataNode1>
             <!-- Child nodes could be null, transform should remove null nodes -->
             <Child1>data</Child1>
             ...
             <Childn>dataN</Childn>
          </DataNode1>
          ...
          <DataNodeN>
             <Child1>data</Child1>
             ...
             <Childn>dataN</Childn>
          </DataNodeN>
       </InquiryResponse>
    </SecondResponse>
 </Response>

今、私は次のことを達成する必要があります:

1)のすべての子ノードをコピーします<InquiryResponse>(ただし、<InquiryResponse>それ自体はコピーしません)

<Confirmation>2)ノードと<Exception>ノードを除外します

3)DataNode内のnullの子を除外します

4)DataNodeに新しい子要素を挿入します

したがって、目的の出力は次のようになります。

 <ID>99999</ID>
 <DataNode1>
   <Child1>data</Child1>
   <ChiildInsert>newData</ChildInsert>
   <Childn>dataN</Childn>
 </DataNode1>
 ...
 <DataNodeN>
    <Child1>data</Child1>
    <ChildInsert>newData</ChildInsert>
    <Childn>dataN</Childn>
 </DataNodeN>

これを行うには、DataNodeごとにテンプレートを作成し(発生する可能性のあるすべての値を知っています)、不要なノードを削除して、nullを無視するマスターコピーテンプレートにすべて適用する必要があると思います。ノード。これは、2.0を使用したXSLTの現在の化身です。完全ではないことはわかっていますが、これは私が得た限りです。

 <xsl:stylesheet version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <!-- Remove Unwanted Nodes -->
  <xsl:template match='Confirmation|Exception'/>

  <!-- DataNode Template -->
  <template match='DataNode1'>
    <xsl:copy>
       <xsl:apply-templates select="@*|node()"/>
       <ChildInsert>
          <xsl:value-of select='newData'/>
       </ChildInsert>
    </xsl:copy>
  </xsl:template>

  <!-- Identity Transform -->
  <xsl:template match='@*|node()'> 
    <xsl:if test='. != ""'>
       <xsl:copy>
         <xsl:apply-templates select='@*|node()'/>
       </xsl:copy>
    </xsl:if>
  </xsl:template>

  </xsl:stylesheet>

これは、Saxon-PE9.3.0.5を使用して生成している出力です。

 <Response>
   <SecondResponse>
     <InquiryResponse>
         <ID>99999</ID>
         <DataNode1>
            <Child1>data</Child1>
            <ChiildInsert>newData</ChildInsert>
            <Childn>dataN</Childn>
         </DataNode1>
         ....
         <DataNodeN>...</DataNodeN>
     </InquiryResponse>
   </SecondResponse>
 </Response>

明らかに、私はそれらを処理する方法を指定していないので、私はまだすべての応答Parentsを取得しています。ただし、テンプレートをXPathに一致させようとすると、XMLではなくデータが取得されます。の子ノードをコピーするだけの別の変換を通過できることはわかって<InquiryResponse>いますが、代わりにもっとエレガントな方法があるはずだと感じました。以下は私がまだ直面している問題/質問です。

1)次のようなテンプレートを使用する<xsl:template match='Response'/>と、応答全体がnullになるため、一致するように識別テンプレートを切り替えようとしましたResponse/SecondResponse/InquiryResponse/*が、結果はテキストデータのみを生成し、XMLは生成しません。

2)<Exception>ノードに値が入力されると、ノードのように削除されるのではなく、コピーされ続け<Confirmation>ます。

3)nullでない子ノードの値を更新したい場合、このようにしますか?いくつかの子ノードを更新するための追加の要件があるので、私はまだその方法を考えています。これは正しい方法のようですが、確認したいと思います。

 <xsl:template match='childNodeA'>
     <childNodeA>
        <xsl:value-of select='someValue/>
     </childNodeA>
 </xsl:template> 

ご不明な点がございましたら、お詫び申し上げますが、ご不明な点がございましたら、お気軽にお問い合わせください。よろしくお願いいたします。

4

1 に答える 1

8

投稿した出力XMLは、ルート要素がないため整形式ではありませんが、このXSLT1.0スタイルシートは必要な処理を実行する必要があります。

スタイルシート

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

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

  <!-- Apply all child nodes; don't copy the element itself -->
  <xsl:template match="Response | SecondResponse | InquiryResponse">
    <xsl:apply-templates/>
  </xsl:template>

  <!-- Drop elements -->
  <xsl:template match="Confirmation | Exception"/>

  <xsl:template match="DataNode1 | DataNode2 | DataNodeN">
    <xsl:copy>
      <!-- Apply Child1, ignore children with no text content -->
      <xsl:apply-templates select="Child1[normalize-space(.)]"/>
      <!-- Insert new element -->
      <ChildInsert>newData</ChildInsert>
      <!-- Apply all other child elements except Child1 -->
      <xsl:apply-templates select="*[normalize-space(.)][not(self::Child1)]"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

入力

<Response>
  <Confirmation>Success</Confirmation>
  <SecondResponse>
     <InquiryResponse>
        <ID>99999</ID>
        <Confirmation>Success</Confirmation>
        <Exception/>
        <!-- The following structure repeats a varying amount of times -->
        <DataNode1>
           <!-- Child nodes could be null, transform should remove null nodes -->
           <Child1>data</Child1>
           <Childn>dataN</Childn>
        </DataNode1>
        <DataNodeN>
           <Child1>data</Child1>
           <Childn>dataN</Childn>
        </DataNodeN>
     </InquiryResponse>
  </SecondResponse>
</Response>

出力

<?xml version="1.0" encoding="utf-8"?>
<ID>99999</ID>
<DataNode1>
  <Child1>data</Child1>
  <ChildInsert>newData</ChildInsert>
  <Childn>dataN</Childn>
</DataNode1>
<DataNodeN>
  <Child1>data</Child1>
  <ChildInsert>newData</ChildInsert>
  <Childn>dataN</Childn>
</DataNodeN>

「null」の意味を指定しなかったため、テキストコンテンツのない要素を意味すると想定したことに注意してください。したがって、上記のコードは次の<Child1>ような要素を削除します。

<Child1>
  <GrandChild1/>
</Child1>
于 2013-02-18T07:22:41.393 に答える