2

特定の要素が存在しない場合に限り、すでに名前空間が設定されているXMLファイルに名前空間を追加する必要があります。

私のXMLドキュメントは次のようになります。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<everyone xmlns="AAA" xmlns:ns2="BBB" xmlns:ns3="CCC" company="TestingCorp">
    <common>Stuff Here</common>
    <ns2:person id="123">
        <ns3:firstname>Billy</ns3:firstname>
        <ns2:lastname>Bobby</ns2:lastname>
    </ns2:person>
</everyone>

...そしてperson要素にns3:firstname要素がない場合は、以下に示すように、新しい名前空間と(xmlns:frog = "FFF"など)およびperson内の追加要素を追加したいと思います。

必要な出力:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<everyone xmlns="AAA" xmlns:ns2="BBB" xmlns:ns3="CCC" xmlns:frog="FFF" company="TestingCorp">
    <common>Stuff Here</common>
    <ns2:person id="123">
        <frog:title>
            <Master/>
        </frog:title>
        <ns2:lastname>Bobby</ns2:lastname>
    </ns2:person>
</everyone>

私のXSLドキュメントは現在次のとおりです。

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

    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>

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

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

</xsl:stylesheet>

....残念ながら、これは機能しません。

私はさまざまなことを試しましたが、XSLTv1.0を使用してこれを達成できないようです。どんな助けでも大歓迎です。

4

1 に答える 1

2

"AAA"まず、スタイルシートでさまざまな名前空間とデフォルトの名前空間を宣言する必要があります

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="AAA"
    xmlns:frog="FFF"
    xmlns:ns2="BBB"
    xmlns:ns3="CCC">

    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>

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

  <!-- for a Person with no firstname, add a frog:title -->
  <xsl:template match="ns2:person[not(ns3:firstname)]">
      <xsl:copy>
          <!-- must handle attributes before elements/text nodes -->
          <xsl:apply-templates select="@*" />
          <frog:title>
              <Master/>
          </frog:title>
          <xsl:apply-templates select="node()" />
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

これにより、

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<everyone xmlns="AAA" xmlns:ns2="BBB" xmlns:ns3="CCC" company="TestingCorp">
    <common>Stuff Here</common>
    <ns2:person id="123">
        <frog:title xmlns:frog="FFF">
            <Master/>
        </frog:title>
        <ns2:lastname>Bobby</ns2:lastname>
    </ns2:person>
</everyone>

xmlns:frog絶対everyoneにそれぞれではなく要素に存在する必要がある場合はfrog:title、別のテンプレートを追加できます

<xsl:template match="/*">
  <xsl:copy>
    <xsl:copy-of select="document('')/xsl:stylesheet/namespace::frog" />
    <xsl:apply-templates select="@*|node()" />
  </xsl:copy>
</xsl:template>

名前空間宣言をスタイルシート要素からコピーします(ただし、これは、要素xmlns:frogが含まれていない場合でも、すべての出力ドキュメントに宣言があることを意味しfrog:*ます)。


copy-of編集:どうやらXalanはからの名前空間を好まないようdocument('')です。代わりに、ドキュメント要素が常に同じ名前になることがわかっている場合は、それをリテラルの結果要素としてハードコーディングできます

<xsl:template match="/*">
  <everyone xmlns:frog="FFF">
    <xsl:copy-of select="namespace::*" />
    <xsl:apply-templates select="@*|node()" />
  </everyone>
</xsl:template>

(技術的には、このテンプレートに明示がなくても、文字通りの結果要素は、宣言されたスタイルシートxmlns:frogのポイントでスコープ内にある名前空間宣言を常に取得するため、必要なことを実行しますが、それを含めると、意図はほぼ間違いなく明確になります)。

このメーリングリストの投稿は、正常に機能しない理由について考えられる洞察を提供しdocument('')ます。

于 2013-02-28T15:21:54.530 に答える