3

これに沿って出力を生成する必要があるXSLがあります。

<moo xmlns="http://api.example.com">
    <foo>1358944586848</foo>
    <bar>
        <a>1</a>
        <b>2</b>
        <c>3</c>
    </bar>
</moo>

私はこのようにそれを行うことができます:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://api.example.com">

    <xsl:template match="/">
        <xsl:element name="moo">
            <!-- and so on -->

ただし、xslファイルでxslプレフィックスを使用するのは嫌いです。これは、xslがかなり乱雑になっていると感じるためです。xpath-default-namespace必要に応じて変換元に設定できるため、XPathでの選択はとにかく簡単です。しかしelement-default-namespace、私が見る限り利用できるものはありません。それでは、どうすれば必要な出力を適切に生成できますか?

私はこれができることを知っています:

<stylesheet version="2.0"
    xmlns="http://www.w3.org/1999/XSL/Transform">

    <template match="/">
        <element name="moo" namespace="http://api.example.com">
            <!-- and so on -->

ただし、作成するすべての要素にこの名前空間を明示的に設定する必要があります。そうしないと、代わりにXSL名前空間になります。それで、xslファイルのデフォルトの名前空間に触れずに特定の名前空間(プレフィックスなし)で要素を作成するクリーンな方法はありますか?


アップデート:

おそらくnamespace-alias何かをすることができると考えましたが、それを使用する方法を理解することはできません。これを試しましたが、出力にまったく違いがないようです。

<stylesheet version="2.0"
    xmlns="http://www.w3.org/1999/XSL/Transform"
xmlns:out="http://api.example.com">

<namespace-alias stylesheet-prefix="out" result-prefix=""/>

    <template match="/">
        <element name="out:moo">
            <!-- and so on -->

namespace-aliasおそらく、私が思っていることをしていないのでしょう:p

JLRisheの回答に基づいて、私が使用した最終的な解決策

remove-prefixes.xsl

<?xml version="1.0" encoding="UTF-8"?>
<stylesheet version="2.0" xmlns="http://www.w3.org/1999/XSL/Transform">
    <template match="/">
        <variable name="result">
            <next-match />
        </variable>
        <apply-templates select="$result" mode="remove-prefixes" />
    </template>

    <template match="*" priority="1" mode="remove-prefixes">
        <element name="{local-name()}" namespace="{namespace-uri()}">
            <apply-templates select="@* | node()" mode="remove-prefixes" />
        </element>
    </template>
    <template match="@*|node()" mode="remove-prefixes">
        <copy>
            <apply-templates select="@* | node()" mode="remove-prefixes" />
        </copy>
    </template>

</stylesheet>

subject.xsl

<!-- snip -->
<import href="remove-prefixes.xsl" />
<!-- snip -->
4

3 に答える 3

3

できることの 1 つは、XSL の結果全体を変数に取り込んでから、末尾のプレフィックスを空白にすることです。

<stylesheet version="2.0" xmlns="http://www.w3.org/1999/XSL/Transform"
                          xmlns:p="http://api.example.com">
  <output method="xml" indent="yes"/>

  <template match="/">
    <variable name="result">
      <p:moo>
        <apply-templates />
      </p:moo>
    </variable>
    <apply-templates select="$result" mode="removePrefix" />
  </template>

  <template match="root">
    <p:something hello="hi">
      <element name="p:somethingelse" />
    </p:something>
  </template>

  <template match="p:*" mode="removePrefix">
    <element name="{local-name()}" namespace="{namespace-uri()}">
      <apply-templates select="@* | node()" mode="removePrefix" />
    </element>
  </template>

  <template match="@* | node()" mode="removePrefix">
    <copy>
      <apply-templates select="@* | node()" />
    </copy>
  </template>
</stylesheet>

この入力で実行すると:

<root>
  <top />
</root>

それは生成します:

<moo xmlns="http://api.example.com">
  <something hello="hi">
    <somethingelse />
  </something>
</moo>
于 2013-01-23T13:16:59.747 に答える
1

アプローチはxmlns:xslまさに「標準」の日であり、XSL の設計者はそれを念頭に置いていたと思います。

XML フラグメントを XSL に直接混在させることが許可されていることに注意してください。その観点から、あなたのアプローチはxsl:element間違いなく、「element-default-namespace」で排除しようとしているものよりもはるかに多くのノイズと混乱を追加します。

だから、私はこれをします:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://api.example.com">

    <xsl:template match="/">
        <moo>
            <!-- and so on -->

編集:

次のようにnamespace-alias動作する可能性があります。

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://api.example.com">

    <namespace-alias stylesheet-prefix="xsl" result-prefix="#default"/>

    <template match="/" xmlns="http://www.w3.org/1999/XSL/Transform">
        <element name="moo">
            <!-- etc -->

またはこのように:

<stylesheet version="2.0"
    exclude-result-prefixes="api" 
    xmlns="http://www.w3.org/1999/XSL/Transform"
    xmlns:api="http://api.example.com">

    <namespace-alias stylesheet-prefix="#default" result-prefix="api"/>

    <template match="/">
        <element name="moo">
            <!-- etc -->
于 2013-01-23T12:55:36.063 に答える
0

特に圧倒的多数の要素がターゲット名前空間ではなく XSL 名前空間にあるスタイルシートがある場合は、混乱についてあなたと同じように感じます。解決策は簡単です。XSL 要素ではなく、出力要素にプレフィックスを付けます。

<stylesheet version="2.0"
    xmlns="http://www.w3.org/1999/XSL/Transform"
    xmlns:o="http://api.example.com">

    <template match="/">
        <o:moo>
            <!-- and so on -->
于 2013-01-23T12:58:34.790 に答える