0

私はこのように構造化されたxmlドキュメントを持っています:-

<catalog xmlns="format_old" xmlns:final="format_new">
  <final:book>
    <final:title>blah</final:title>
    <final:author>more blah</final:author>
  </final:book>
  <book>
    <description title="blah2"/>
    <writer name="more blah2"/>
  </book>
</catalog>

明らかに、これは問題の単純化されたバージョンです。私がやりたいのは、これを次のようなものに変換することです:-

<catalog xmlns="format_new">
  <book>
    <title>blah</title>
    <author>more blah</author>
  </book>
  <book>
    <title>blah2</title>
    <author>more blah2</author>
  </book>
</catalog>

私が今持っているスタイルシートはこのようなものです:-

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

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

<xsl:template match="//orig:book">
  <xsl:element name="title">
    <xsl:value-of select="./orig:description/@title" />
  </xsl:element>
  <xsl:element name="author">
    <xsl:value-of select="./orig:writer/@name" />
  </xsl:element>
</xsl:template>

</xsl:stylesheet>

これにより、次のような出力が得られます:-

<catalog xmlns="format_old">
  <book xmlns="format_new">
    <title>blah</title>
    <author>more blah</author>
  </book>
  <book xmlns:orig="format_old" xmlns="format_new">
    <title>blah2</title>
    </author>more blah2</author>
  </book>
</catalog>

このスタイルシートには2つの問題があります:-

1。)(主要な問題)ルート要素のデフォルトの名前空間を変更するのではなく、ルート要素がコピーされます。したがって、基本的に、カタログ要素はまだ名前空間format_oldにあります。

2。)(マイナーな問題)これにより、要素が次のように変換されます:-

<book xmlns:orig="format_old" xmlns="format_new">
  ...
</book>

ルート要素から名前空間を取得する代わりに、

<book>
  ...
</book>

ここで何が欠けていますか?Xalan-Cを使用しています。

4

2 に答える 2

2

私は次のことをすべきだと思います:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns="format_new"
    xmlns:ns1="format_old"
    exclude-result-prefixes="ns1"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="@* | text() | comment() | processing-instruction()">
  <xsl:copy/>
</xsl:template>

<xsl:template match="*">
  <xsl:element name="{local-name()}">
    <xsl:apply-templates select="@* | node()"/>
  </xsl:element>
</xsl:template>

<xsl:template match="ns1:book/ns1:description[@title]">
  <title>
    <xsl:value-of select="@title"/>
  </title>
</xsl:template>

<xsl:template match="ns1:book/ns1:writer[@name]">
  <author>
    <xsl:value-of select="@name"/>
  </author>
</xsl:template>

</xsl:stylesheet>

Saxon6.5.5は入力をに変換します

<?xml version="1.0" encoding="utf-8"?><catalog xmlns="format_new">
  <book>
    <title>blah</title>
    <author>more blah</author>
  </book>
  <book>
    <title>blah2</title>
    <author>more blah2</author>
  </book>
</catalog>
于 2012-09-24T17:47:04.587 に答える
1

あなたは近くにいます。デフォルトのテンプレートは、他のテンプレートがないものをすべて取得します。

あなたの最初の問題は、彼らがorig:catalog要素を取得し、それを変更せずに書き出すことです。これは、あなたが望むものではないことがわかります。簡単な修正:テンプレートを追加します。

2番目の問題は、出力の名前空間宣言を管理することです。ここでは、いくつかのテクニックが役立ちます。

  • 仕様またはお気に入りのXSLTリファレンスにあるxsl:exclude-result-prefixesのドキュメントを注意深く読んでください。これを使用して、古い名前空間の名前空間宣言を使用する必要がないことをプロセッサに通知します。

  • リテラル結果要素からの出力が常にスタイルシートのLREにあるすべてのinscope名前空間プレフィックスを運ぶという事実を利用したい場合は、リテラル結果要素の代わりにxsl:elementコンストラクターを使用してください。詳細については、このSOの質問を参照してください。

  • SAXまたはお気に入りのエディターで簡単なフィルターを作成して、名前空間を宣言する場所と方法を完全に制御できるようにします。(XSLTの設計では、名前空間の宣言については非常に心配する必要があると考えられているため、名前空間の宣言を適切に制御することは困難です。)

  • 出力に無関係な名前空間宣言が含まれている場合はあまり気にしないようにトレーニングし、すべてが正しくバインドされている限り、ダウンストリームコンシューマーに正しいことを実行するように記述して、無関係な名前空間宣言に煩わされないようにします。

さまざまな人々が、これらのさまざまな手法でさまざまなレベルの成功を収めています。私自身、最後のものが特に効果的だと思います、そしてそれが私に故障したときだけ他のものについて心配します。

于 2012-09-24T17:57:26.713 に答える