I有し、このような構造を有する所与のソースXML文書:XSLT - 識別パターンと関連のノードのコンテキストを変更する問題
<?xml version="1.0" encoding="UTF-8"?>
<sample>
<definition>
<variable>
<name>object01_ID_138368350261919620</name>
<value>NUL</value>
</variable>
<variable>
<name>param01_ID_138368350261919621</name>
<value>10</value>
</variable>
<variable>
<name>param02_ID_138368350261919622</name>
<value>100</value>
</variable>
</definition>
<override>
<assignment>
<name>object01_ID_138368350261919620</name>
<path>module01/object01</path>
</assignment>
<assignment>
<name>param01_ID_138368350261919621</name>
<path>module01/object01/param01</path>
</assignment>
<assignment>
<name>param02_ID_138368350261919622</name>
<path>module01/object01/param02</path>
</assignment>
</override>
</sample>
ソースXMLの特性がある:
各<assignment>
<override>
要素内の要素は、<definition>
要素内のちょうど1つの<variable>
要素に対応します。この1:1の関係は、<name>
要素の内容によって確立されます。
変換し、ターゲットXMLの要件は次のとおりです。
<path>
要素の内容のパターンに応じて、<override>
要素で<assignment>
要素の中に、私は新しい<assignment>
要素を追加したいです。注目すべき重要な点は、<assignment>
要素が主要な情報であることです。したがって、最初に新しい<assignment>
要素の<path>
と<name>
内容を作成し、これに対応して、対応する新しい<variable>
要素と同じ<name>
内容と特定の<value>
要素を作成し、最後の位置に挿入する必要があります<definition>
要素。
<?xml version="1.0" encoding="UTF-8"?>
<sample>
<definition>
<variable>
<name>param00_ID_138368350261919620</name>
<value>NUL</value>
</variable>
<variable>
<name>param01_ID_138368350261919621</name>
<value>10</value>
</variable>
<variable>
<name>param02_ID_138368350261919622</name>
<value>100</value>
</variable>
<variable>
<name>Param03_ID_138368350261919623</name>
<value>1000</value>
</variable>
</definition>
<override>
<assignment>
<name>param00_ID_138368350261919620</name>
<path>module01/object01</path>
</assignment>
<assignment>
<name>param01_ID_138368350261919621</name>
<path>module01/object01/param01</path>
</assignment>
<assignment>
<name>param02_ID_138368350261919622</name>
<path>module01/object01/param02</path>
</assignment>
<assignment>
<name>Param03_ID_138368350261919623</name>
<xpath>module01/object01/param03</xpath>
</assignment>
</override>
</sample>
変換のための私のXSL 2.0スタイルシート:たとえば、param03を追加するために、右の結果は次のようになります恒等変換のために
を、私はきめの細かい制御アイデンティティルールを使用することを選びだしてきました、 [Dimitre Novatchev]で推奨されています。 処理param03テンプレートを適用して、新しい<assignment>
要素を作成し、その具体的な内容は<path>
と<name>
です。そのテンプレート内で、for-each
要素を使用して<definition>
要素にノードコンテキストを変更し、最後に対応する<name>
コンテンツと特定の<value>
コンテンツを持つ新しい<variable>
要素を追加します。このスタイルシートはSaxon HE 9.5でテストされています。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="fo xs fn">
<!--
global declarations ==========================================================
-->
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- randomid here is just a fake for sake of simplification -->
<xsl:variable name="randomid" select="138368350261919623"/>
<!--
template - identity ==========================================================
-->
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()[1]"/>
</xsl:copy>
<xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
<!--
template - variable assignment ===============================================
-->
<xsl:template name="variable_assignment">
<xsl:param name="value_node_name"/>
<xsl:param name="value_node_path"/>
<xsl:message select="'processing: variable assignment'"/>
<xsl:message select="concat('applying name: ', $value_node_name)"/>
<xsl:message select="concat('applying path: ', $value_node_path)"/>
<xsl:call-template name="identity"/>
<assignment>
<name>
<xsl:value-of select="$value_node_name"/>
</name>
<xpath>
<xsl:value-of select="$value_node_path"/>
</xpath>
</assignment>
</xsl:template>
<!--
template - processing param03 =============================================
-->
<xsl:template match="/sample/override[not(assignment
/path[matches(text(), '.*/object01/param03$')])]
/assignment[path[matches(text(), '.*/object01$')]]">
<!-- setting params -->
<xsl:param name="value_node_name_target">
<xsl:value-of select="concat('Param03_ID', '_', $randomid)"/>
</xsl:param>
<xsl:param name="value_node_path_target">
<xsl:value-of select="concat(./path, '/param03')"/>
</xsl:param>
<xsl:param name="value_node_value_target" select="'1000'"/>
<!-- processing variable assignment -->
<xsl:call-template name="variable_assignment">
<xsl:with-param name="value_node_name" select="$value_node_name_target"/>
<xsl:with-param name="value_node_path" select="$value_node_path_target"/>
</xsl:call-template>
<!-- processing variable definition -->
<xsl:for-each select="/sample/definition/*[position()=last()]">
<xsl:message select="'processing: variable definition'"/>
<xsl:message select="concat('Here we are: ', .)"/>
<xsl:message select="concat('applying name: ', $value_node_name_target)"/>
<xsl:message select="concat('applying value: ', $value_node_value_target)"/>
<xsl:call-template name="identity"/>
<variable>
<name>
<xsl:value-of select="$value_node_name_target"/>
</name>
<value>
<xsl:value-of select="$value_node_value_target"/>
</value>
</variable>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
結果として間違ったXMLは次のとおりです。私が得た
<?xml version="1.0" encoding="UTF-8"?>
<sample>
<definition>
<variable>
<name>object01_ID_138368350261919620</name>
<value>NUL</value>
</variable>
<variable>
<name>param01_ID_138368350261919621</name>
<value>10</value>
</variable>
<variable>
<name>param02_ID_138368350261919622</name>
<value>100</value>
</variable>
</definition>
<override>
<assignment>
<name>object01_ID_138368350261919620</name>
<path>module01/object01</path>
</assignment>
<assignment>
<name>param01_ID_138368350261919621</name>
<path>module01/object01/param01</path>
</assignment>
<assignment>
<name>param02_ID_138368350261919622</name>
<path>module01/object01/param02</path>
</assignment>
<assignment>
<name>Param03_ID_138368350261919623</name>
<xpath>module01/object01/param03</xpath>
</assignment>
<variable>
<name>param02_ID_138368350261919622</name>
<value>100</value>
</variable>
<variable>
<name>Param03_ID_138368350261919623</name>
<value>1000</value>
</variable>
</override>
</sample>
問題は次のとおりである:
- ノードコンテキストが変更されない状態になります。新しい
<variable>
要素は最後の位置で<override>
要素に追加され、代わりに<definition>
要素に追加されます。 - さらに、
<definition>
要素の最後の<variable>
要素が<override>
要素にコピーされます。それは私が望むものではありません。
ヘルプが必要です。
誰かがアドバイスを受けることができれば本当に感謝しています。上記のように、問題と正しい振る舞いを取り除くためにXSLTを適応させる必要があります。
多くのありがとうございます。
私によって適合あなたが提案したXSLT 2.0、:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="fo xs fn">
<!--
global declarations ==========================================================
-->
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- baserandom here is just a fake for sake of simplification -->
<xsl:param name="baserandom" select="138368350261919623"/>
<!--MOVED PARAMS FROM ORIGINAL TEMPLATE HERE SO THEY CAN BE USED BY MULTIPLE TEMPLATES -->
<!--xsl:param name="value_node_path"-->
<!--I LEFT THE PREDICATE BECAUSE IT APPEARS THAT THERE COULD BE MORE THAN ONE override ELEMENT.-->
<!--xsl:value-of select="concat(/sample/override[not(assignment/path[matches(text(), '.*/object01/param03$')])]
/assignment[1]/path, '/param03')"/>
</xsl:param>
<xsl:param name="value_node_value" select="'1000'"/-->
<!--
template - identity ==========================================================
-->
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()[1]"/>
</xsl:copy>
<xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
<!--
template - definition ========================================================
-->
<!--REPLACES THE xsl:for-each THAT PROCESSES THE VARIABLE DEFINITION-->
<xsl:template match="definition/*[last()]">
<xsl:param name="value_node_name"/>
<xsl:param name="value_node_value"/>
<xsl:call-template name="identity"/>
<xsl:if test="$value_node_name">
<xsl:message select="'processing: variable definition'"/>
<xsl:message select="concat('Here we are: ', .)"/>
<xsl:message select="concat('applying name: ', $value_node_name)"/>
<xsl:message select="concat('applying value: ', $value_node_value)"/>
<variable>
<name>
<xsl:value-of select="$value_node_name"/>
</name>
<value>
<xsl:value-of select="$value_node_value"/>
</value>
</variable>
</xsl:if>
</xsl:template>
<!--
template - processing param03 =============================================
-->
<xsl:template match="/sample/override[not(assignment/path[matches(text(), '.*/object01/param03$')])]
/assignment[path[matches(text(), '.*/object01$')]]">
<!-- name -->
<xsl:param name="value_node_name">
<xsl:value-of select="concat('param03_ID', '_', $baserandom)"/>
</xsl:param>
<!-- path -->
<xsl:param name="value_node_path">
<xsl:value-of select="concat(./path, '/param03')"/>
</xsl:param>
<!-- value -->
<xsl:param name="value_node_value" select="'1000'"/>
<!-- processing definition -->
<xsl:apply-templates select="/sample/definition/*[last()]">
<xsl:with-param name="value_node_name" select="$value_node_name"/>
<xsl:with-param name="value_node_value" select="$value_node_value"/>
</xsl:apply-templates>
<!-- processing assignment -->
<xsl:message select="'processing: variable assignment'"/>
<xsl:message select="concat('applying name: ', $value_node_name)"/>
<xsl:message select="concat('applying path: ', $value_node_path)"/>
<xsl:call-template name="identity"/>
<assignment>
<name>
<xsl:value-of select="$value_node_name"/>
</name>
<path>
<xsl:value-of select="$value_node_path"/>
</path>
</assignment>
</xsl:template>
</xsl:stylesheet>
(まだ間違った)結果のXML:
<?xml version="1.0" encoding="UTF-8"?>
<sample>
<definition>
<variable>
<name>object01_ID_138368350261919620</name>
<value>NUL</value>
</variable>
<variable>
<name>param01_ID_138368350261919621</name>
<value>10</value>
</variable>
<variable>
<name>param02_ID_138368350261919622</name>
<value>100</value>
</variable>
</definition>
<override>
<variable>
<name>param02_ID_138368350261919622</name>
<value>100</value>
</variable>
<variable>
<name>param03_ID_138368350261919623</name>
<value>1000</value>
</variable>
<assignment>
<name>object01_ID_138368350261919620</name>
<path>module01/object01</path>
</assignment>
<assignment>
<name>param01_ID_138368350261919621</name>
<path>module01/object01/param01</path>
</assignment>
<assignment>
<name>param02_ID_138368350261919622</name>
<path>module01/object01/param02</path>
</assignment>
<assignment>
<name>param03_ID_138368350261919623</name>
<path>module01/object01/param03</path>
</assignment>
</override>
</sample>
"param03を追加する例について..." * - 'param03' *が追加されたどのように* ?一番上に表示されているソースXMLを、あなたが投稿した結果XMLにどのように変換するべきかは、私には分かりません。 – ABach
_param03_の例では、 ''要素を ' '要素内に追加することで、両方のXSLTがうまく機能していることを示したいと思います(コメント_"処理変数割り当て "_の後のコードを参照)。やってみなよ。私が記述した問題は、対応する ''要素を ''要素に追加するために必要な変換の中で生じました(コメント_ "処理後のコード_ _変数定義" _を参照してください。 –
非常に長く冗長であるため、この質問に答えることにユーザーが躊躇していると思います。入力XMLを変更する方法をごく少数の文章で記述してください(ただし、 –