2

正しい XSL 変換を取得するために助けが必要です。ソース XML がそのままコピーされ、ターゲット XML ファイルに必要な更新が行われることを期待しています。現在、私は 2 つのことを試みています。1 つ目は、ソースをターゲット XML にコピーすることです。2 つ目は、ルート要素の名前空間 URL とバージョン属性を更新することです。以下のコードを見つけて、ターゲット xml でルート要素のみを取得している、コンテンツが見つからない、ルート要素の終了タグが見つからない、属性バージョンが更新されていないなどの問題が発生していることをお知らせください。

ソース XML-

<soapenv:Envelope 
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:v1="http://www.abc.com/s/v1.0">
<soapenv:Header/>
<soapenv:Body>
<v1:QueryRequest version="1">
<subject>
<dataList>
<!--1 or more repetitions:-->
<dataset>
<type>company</type>
<value>abc</value>
</dataset>
<dataset>
<type>user</type>
<value>xyz</value>
</dataset>
</dataList>
</subject>
<!--Optional:-->
<testList>
<!--1 or more repetitions:-->
<criteria>
<type>test</type>
<value>972</value>
</criteria>
<criteria>
<type>test2</type>
<value>false</value>
</criteria>
</testList>
</v1:QueryRequest>
</soapenv:Body>
</soapenv:Envelope>

XSL ファイル :-

<?xml version="1.0" encoding="utf-8"?>
<xsl:transform version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:old="http://www.abc.com/s/v1.0" exclude-result-prefixes="old">    
<xsl:output method="xml" encoding="utf-8" indent="yes"  version="1.0" />

<xsl:param name="newversion" select="2.0"> </xsl:param>
<!-- replace namespace of elements in old namespace -->

<xsl:template match="old:*">
<xsl:element name="{local-name()}" namespace="http://www.abc.com/s/v2.0">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>

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

<xsl:template match="//*[local-name()='QueryRequest']/@version">
<xsl:attribute name="version">
<xsl:value-of select="$newversion"/>
</xsl:attribute>

</xsl:template>     

上記の XSL ファイルを使用した出力:-

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
</soapenv:Header>
<soapenv:Body><ns7:QueryRequest version="1" xmlns=""
xmlns:ns6="http://www.abc.com/s/v1.0" 
xmlns:ns7="http://www.abc.com/s/v2.0"/>

</soapenv:Body>
</soapenv:Envelope>

"

期待される出力:

<soapenv:Envelope 
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:v2="http://www.abc.com/s/v2.0">
<soapenv:Header/>
<soapenv:Body>
<v2:QueryRequest version="2.0">
<subject>
<dataList>
<!--1 or more repetitions:-->
<dataset>
<type>company</type>
<value>abc</value>
</dataset>
<dataset>
<type>user</type>
<value>xyz</value>
</dataset>
</dataList>
</subject>
<!--Optional:-->
<testList>
<!--1 or more repetitions:-->
<criteria>
<type>test</type>
<value>972</value>
</criteria>
<criteria>
<type>test2</type>
<value>false</value>
</criteria>
</testList>
</v2:QueryRequest>
</soapenv:Body>
</soapenv:Envelope>

この変換をトリガーする Spring 構成コード -

<int-xml:xslt-transformer  id="v2transformer"                                     xsl-resource="classpath:transformtoversion2.xslt" 
input-channel="AChannel" output-channel="BChannel" 
result-transformer="resultTransformer"> 
</int-xml:xslt-transformer> 
4

1 に答える 1

3

xsl:stylesheet私にとっては、ルート要素の名前をではなく に変更して XSLT を修正するとxsl:transform、ほぼ正しい出力が得られます。

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://www.abc.com/s/v1.0">
<soapenv:Header/>
<soapenv:Body>
<QueryRequest xmlns="http://www.abc.com/s/v2.0" version="2">
<subject xmlns="">
<dataList>
<!--1 or more repetitions:-->
<dataset>
<type>company</type>
<value>abc</value>
</dataset>
<dataset>
<type>user</type>
<value>xyz</value>
</dataset>
</dataList>
</subject>
<!--Optional:-->
<testList xmlns="">
<!--1 or more repetitions:-->
<criteria>
<type>test</type>
<value>972</value>
</criteria>
<criteria>
<type>test2</type>
<value>false</value>
</criteria>
</testList>
</QueryRequest>
</soapenv:Body>
</soapenv:Envelope>

version="2"ではなく、必要なものとの唯一の意味的に重要な違いversion="2.0"。これは、にいくつかの引用符を追加することで修正できます

<xsl:param name="newversion" select="'2.0'" />

param 値を数値2 ではなく文字列2.0 に設定します。


外見上の違いについては、ルート要素から未使用のものを削除し、デフォルトの名前空間の代わりに要素にxmlns:v1プレフィックスを使用する場合 (これは、子のために廃止されます)、このようなものがもっと必要ですQueryRequestxmlns=""

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:old="http://www.abc.com/s/v1.0" exclude-result-prefixes="old"
xmlns:v2="http://www.abc.com/s/v2.0">    
  <xsl:output method="xml" encoding="utf-8" indent="yes"  version="1.0" />

  <xsl:param name="newversion" select="'2.0'"/>

  <!-- fix namespace declarations on root element -->
  <xsl:template match="/*">
    <xsl:element name="{name()}" namespace="{namespace-uri()}">
      <!-- copy the v2: binding from the stylesheet document -->
      <xsl:copy-of select="document('')/xsl:stylesheet/namespace::v2" />
      <xsl:apply-templates select="@* | node()" />
    </xsl:element>
  </xsl:template>

  <!-- replace namespace of elements in old namespace -->
  <xsl:template match="old:*">
    <xsl:element name="v2:{local-name()}">
      <xsl:apply-templates select="@* | node()"/>
    </xsl:element>
  </xsl:template>

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

  <xsl:template match="old:QueryRequest/@version">
    <xsl:attribute name="version">
      <xsl:value-of select="$newversion"/>
    </xsl:attribute>
  </xsl:template>     
</xsl:stylesheet>

元のタグから名前空間バインディングをコピーするため、テンプレート<xsl:element>の代わりに使用します。<xsl:copy>/*copy


<type>コメントから、すべての値を大文字にする必要があります。これは、テンプレートを 1 つ追加するだけで実現できます。

<xsl:template match="type/text()">
  <xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz',
                                     'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" />
</xsl:template>

to-upper-caseXPath 1.0 には単純な関数はありませんがtranslate(X, Y, Z)、文字列 X を調べて Y の各文字を Z の同じ位置にある文字に置き換える を使用できます。

これにより、すべての type要素が変換されます。条件タイプではなくデータセット タイプのみを変換する場合は、より具体的なmatch="dataset/type/text()".

于 2013-09-17T18:09:34.243 に答える