私は、さらに処理するためにコピーして更新する必要があるxmlを使用しています。私が抱えている問題は、これを行うための効率的な方法を見つけられなかったことです。基本的に、条件付きで一部のデータを更新してから、更新されていないすべてのノードをコピーしたいと考えています。これが困難な理由は、ボリュームが大きく、コピーするノードの数と名前が異なるためです。また、テキスト値を持たないノードをコピーしたくありません。次に例を示します。
入力 XML
<root>
<PersonProfile xmlns:'namespace'>
<ID>0001</ID>
<Name>
<FirstName>Jonathan</FirstName>
<PreferredName>John</PreferredName>
<MiddleName>A</MiddleName>
<LastName>Doe</LastName>
</Name>
<Country>US</Country>
<Biirthdate>01-01-1980</Birthdate>
<BirthPlace>
<City>Townsville</City>
<State>OR</State>
<Country>US</Country>
</Birthplace>
<Gender>Male</Gender>
<HomeState>OR</HomeState>
...
<nodeN>text</nodeN>
</PersonProfile>
</root>
「PersonProfile」ノードは、「ルート」要素内のいくつかのノード セットの 1 つにすぎず、それぞれに独自のデータ サブセットがあります。郵送先住所、緊急連絡先情報など。私がしようとしているのは、変数に新しい値がある場合にノードを更新し、更新されなかったすべてのノードをコピーすることです。
ここに私の現在の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">
<xsl:variable name='updateData' select='document("report")'/>
<!-- Identity Transform -->
<xsl:template match='@* | node()'>
<xsl:if test'. != ""'>
<xsl:copy>
<xsl:apply-templates select='@* | node()'/>
</xsl:copy>
</xsl:if>
</xsl:template>
<!-- Template to update Person Profile -->
<xsl:template match='PersonProfile'>
<xsl:copy>
<xsl:apply-templates select='*'/>
<xsl:element name='Name'>
<xsl:if test='exists($updateData/Preferred)'>
<xsl:element name='FirstName'>
<xsl:value-of select='$reportData/FirstName'/>
</xsl:element>
</xsl:if>
<xsl:if test='exists($updateData/Preferred)'>
<xsl:element name='PreferredName'>
<xsl:value-of select='$updateData/Preferred'/>
</xsl:element>
</xsl:if>
<xsl:if test='exists($updateData/Middle)'>
<xsl:element name='MiddleName'>
<xsl:value-of select='$updateData/Middle'/>
</xsl:element>
</xsl:if>
<xsl:if test='exists($updateData/LastName)'>
<xsl:element name='LastName'>
<xsl:value-of select='$updateData/wd:LastName'/>
</xsl:element>
</xsl:if>
</xsl:element>
<xsl:if test='exists($updateData/Country)'>
<xsl:element name='Country'>
<xsl:value-of select='$updateData/Country'/>
</xsl:element>
</xsl:if>
....
<!-- follows same structure until end of template -->
</xsl:copy>
</xsl:template>
<!-- More Templates to Update other Node sets -->
</xsl:stylesheet>
現在起こっていることは、すべてのノードをコピーしてから更新値を追加していることです。Saxon-PE 9.3.0.5 を使用すると、次のような出力が得られます。
サンプル出力
<root>
<PersonProfile xmlns:'namespace'>
<ID>0001</ID>
<Name>
<FirstName>Jonathan</FirstName>
<PreferredName>John</PreferredName>
<MiddleName>A</MiddleName>
<LastName>Doe</LastName>
</Name>
<Country>US</Country>
<Biirthdate>01-01-1980</Birthdate>
<BirthPlace>
<City>Townsville</City>
<State>OR</State>
<Country>US</Country>
</Birthplace>
<Gender>Male</Gender>
<HomeState>OR</HomeState>
...
<nodeN>text</nodeN>
<PreferredName>Jonathan</PreferredName>
<HomeState>WA</HomeState>
</PersonProfile>
</root>
PersonProfile のすべてのノードにテンプレートを適用していて、除外するノードを指定できるため、これが発生していることに気付きましたが、ノードのボリュームが 30 以上になる可能性があるため、これは非常に貧弱な解決策であると感じています。それには、それぞれに書かれた値が必要です。これらの各ノードを明示的にリストするよりも、XML の方がより洗練されたソリューションを備えていると私は信じています。私はこのようなアウトをしたいと思います:
望ましい出力
<root>
<PersonProfile xmlns:'namespace'>
<ID>0001</ID>
<Name>
<FirstName>Jonathan</FirstName>
<PreferredName>Jonathan</PreferredName>
<MiddleName>A</MiddleName>
<LastName>Doe</LastName>
</Name>
<Country>US</Country>
<Biirthdate>01-01-1980</Birthdate>
<BirthPlace>
<City>Townsville</City>
<State>OR</State>
<Country>US</Country>
</Birthplace>
<Gender>Male</Gender>
<HomeState>WA</HomeState>
...
<nodeN>text</nodeN>
</PersonProfile>
</root>
誰かが xml 構造で機能するテンプレート構造を作成するのを手伝ってくれたら、大いに感謝します。Person Profile のような同様のノード構造があり、それを適用する必要があるため、「再利用可能」である必要がありますが、ノード名や要素数などが異なります。
助けてくれてありがとう!
- J