2

XSLT を使用して、入力ドキュメントのプレフィックスではなく、スタイルシートの名前空間プレフィックスを使用する出力を取得する方法を考えています。例として、この非常に単純化されたドキュメントを考えると:

<?xml version="1.0"?>
<a:node xmlns:a="urn:schemas:blah:"/>

そして、次の XSL 変換:

<?xml version="1.0"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:blah="urn:schemas:blah:" version="2.0">
   <xsl:output indent="yes">
   <xsl:template match="/blah:node">
      <xsl:copy/><!-- marked -->
   </xsl:template>
</xsl:transform>

プロセッサー (重要な場合は Saxon8) は接頭辞「blah:」と「a:」の同等性を認識していることがわかりますが、たとえばfn:in-scope-prefixes()は「blah」を表示せず、「 a'. <!-- marked -->上記の行を次のように変更します。

<node><xsl:value-of select="in-scope-prefixes(.)"/></node>

出力:

<?xml version="1.0" encoding="UTF-8"?>
<node xmlns:blah="urn:schemas:blah:">xml a</node>

入力ファイルがプレフィックス「a」を呼び出すことを事前に知らずに、入力プレフィックス「a」を「何とか」にマップするにはどうすればよいですか? (だから<xsl:namespace-alias/>私にはうまくいきません。)

さらなる文脈として、より良い解決策を指し示す場合、これは外部で生成された XML ドキュメントを表示するためのものです。外部プロセスは、自動生成されたプレフィックス 'a:'、'b:'、'c:' などを使用して入力ドキュメントを作成します。これらのプレフィックスを、より使いやすい名前空間プレフィックスを使用して表示できるようにしたいと考えています。

更新: in-scope-prefixes() の動作は、静的に既知の名前空間の定義によって説明されています

4

3 に答える 3

3

この変換( XSLT 1.0 と XSLT 2.0 の両方(属性を変更するだけversion)):

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

  <my:namespaces>
    <ns prefix="blah" uri="urn:schemas:blah:"/>
    <ns prefix="foo" uri="uff:anotherNamespace"/>
  </my:namespaces>

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

 <xsl:template match=
 "*[namespace-uri()=document('')/*/my:namespaces/*/@uri]">
  <xsl:variable name="vNS" select=
  "document('')/*/my:namespaces/*
                   [@uri=namespace-uri(current())]"/>
  <xsl:element name="{$vNS/@prefix}:{local-name()}"
       namespace="{namespace-uri()}">
   <xsl:copy-of select=
    "namespace::*[not(. = namespace-uri(current()))]"/>
   <xsl:copy-of select="@*"/>
   <xsl:apply-templates/>
  </xsl:element>
 </xsl:template>
</xsl:stylesheet>

XML ドキュメントをコピーし、このドキュメントが選択した名前空間に使用するプレフィックスのみを、指定したプレフィックスに置き換えます。

この XML ドキュメントに適用した場合:

<t>
    <a:node xmlns:a="urn:schemas:blah:"/>
    <b:node xmlns:b="urn:schemas:blah:"/>
    <c:node xmlns:c="uff:anotherNamespace"/>
</t>

必要な結果が生成されます:

<t>
   <blah:node xmlns:blah="urn:schemas:blah:"/>
   <blah:node xmlns:blah="urn:schemas:blah:"/>
   <foo:node xmlns:foo="uff:anotherNamespace"/>
</t>
于 2010-07-22T01:50:07.250 に答える
1

恒等変換とこのテンプレートはどうですか:

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

これが XSLT 2.0 で最も洗練された方法であるかどうかはわかりませんが、うまくいきます。

于 2010-07-21T21:42:12.803 に答える
0

<xsl:namespace-alias ...>トップレベル要素の仕様を見てください。私はそれがあなたが望むものを達成すると信じています。

于 2010-07-21T21:34:41.733 に答える