0

XSLT 出力で名前空間が繰り返されるのを避けたいと考えています。

(Microsoft の DataContractSerializer が実際に適切に処理するのに適していると判断できるように、XSLT を使用して一部の XML を処理しています。DCS が気に入らないと思われることの 1 つは、同じ名前空間を複数回定義することです。)

XXX要素の下からすべての「特性」要素を取得し、次のように新しい配列要素にグループ化しています。

<xsl:stylesheet version="1.0" 
              xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
              xmlns:feature="some namespace">
<xsl:template match="feature:XXX">
  <xsl:copy>
    <feature:Characteristics>
      <xsl:apply-templates select="feature:Characteristics"/>
     </feature:Characteristics>
    <xsl:copy-of select="*[not(self::feature:Characteristics)]" />
  </xsl:copy>
</xsl:template>
<xsl:template match="feature:Characteristics">
  <arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
    <xsl:value-of select="." />
  </arrays:unsignedShort>
</xsl:template>
</xsl:stylesheet>

"feature" 名前空間は、XSLT ファイルの先頭で定義されています。ただし、値 "feature" はソース XML には含まれず、任意のプレフィックス (通常は "h") になります。問題は、この XSLT を使用すると、名前空間が出力 XML の 2 つのプレフィックスに割り当てられることです。入力 XML の元の名前空間 (通常は "h") と、XSLT によって生成される "feature" です。(有効な XML ですが、これは貧しい Microsoft を混乱させます。)

したがって、代わりに現在の要素の名前空間を参照することで、出力 XML で「機能」名前空間を定義することを完全に避けたいと思います。これについてバリアントを試しましたが、現在のコンテキスト ノードの名前空間プレフィックスを取得するために xsl:element の名前空間の値を正しく設定する方法がわかりません...

<xsl:stylesheet version="1.0" 
              xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
              xmlns:feature="some namespace">
  <xsl:template match="feature:XXX">
   <xsl:copy>
    <xsl:element name="Characteristics" namespace="{???}">
      <xsl:apply-templates select="feature:Characteristics"/>
    </xsl:element>
    <xsl:copy-of select="*[not(self::feature:Characteristics)]" />
  </xsl:copy>
</xsl:template>
  <xsl:template match="feature:Characteristics">
  <arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
    <xsl:value-of select="." />
  </arrays:unsignedShort>
</xsl:template>
</xsl:stylesheet>

サンプル入力:

<h:XXX xmlns:h="http://stackoverflow.com">
 <h:Characteristics>7</h:Characteristics>
 <h:Characteristics>11</h:Characteristics>
 <h:Characteristics>12</h:Characteristics>
 <h:ProductName>blah</h:ProductName>
 <h:Vendor>blah</h:Vendor>
 <h:Version></h:Version>
</h:XXX>

名前空間を繰り返す (悪い):

<h:XXX xmlns:h="http://stackoverflow.com">
 <feature:Characteristic xmlns:feature="http://stackoverflow.com">
      <arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">7</arrays:unsignedShort>
      <arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">11</arrays:unsignedShort>
      <arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">12</arrays:unsignedShort>
 </feature:Characteristic>
 <h:ProductName>blah</h:ProductName>
 <h:Vendor>blah</h:Vendor>
 <h:Version></h:Version>
</h:XXX>

望ましい出力:

<h:XXX xmlns:h="http://stackoverflow.com">
 <h:Characteristic>
      <arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">7</arrays:unsignedShort>
      <arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">11</arrays:unsignedShort>
      <arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">12</arrays:unsignedShort>
 </h:Characteristic>
 <h:ProductName>blah</h:ProductName>
 <h:Vendor>blah</h:Vendor>
 <h:Version></h:Version>
</h:XXX>

この XSLT はほとんど機能しますが、"h" 値をハードコーディングする必要があるため、代わりに任意の値をサポートしたいと考えています。

<?xml version ="1.0" encoding="iso-8859-1"?>
  <xsl:stylesheet version="1.0" 
              xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
              xmlns:feature="some ns"
              xmlns:h="some ns"
              exclude-result-prefixes="h">

<xsl:template match="feature:XXX">
  <xsl:copy>
    <h:Characteristic>
      <xsl:apply-templates select="feature:Characteristics"/>
    </h:Characteristic>
    <xsl:copy-of select="*[not(self::feature:Characteristics)]" />
  </xsl:copy>
</xsl:template>

<xsl:template match="feature:Characteristics">
  <arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
    <xsl:value-of select="." />
  </arrays:unsignedShort>
 </xsl:template>

 </xsl:stylesheet>
4

3 に答える 3

1

featureその名前空間を削除しました。私の理解が正しければ、 と同じ URI が含まれていますhね。

<xsl:stylesheet version="1.0"
              xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
              xmlns:h="http://stackoverflow.com">
  <xsl:output method="xml" indent="yes" />
  <xsl:template match="h:XXX" >
    <xsl:copy>
      <h:Characteristics>
        <xsl:apply-templates select="h:Characteristics"/>
      </h:Characteristics>
      <xsl:copy-of select="*[not(self::h:Characteristics)]" />
    </xsl:copy>
  </xsl:template>
  <xsl:template match="h:Characteristics">
    <arrays:unsignedShort 
        xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
      <xsl:value-of select="." />
    </arrays:unsignedShort>
  </xsl:template>
</xsl:stylesheet>
于 2010-01-06T00:20:00.107 に答える
1

これは私にとってはうまくいくようです。もっと簡単な方法があるはずですが、現時点では考えられません。これはすべて、name()関数を使用してルート名のプレフィックス付きの名前を取得し、substring-before()を使用してプレフィックスを取得し、値を再構築してエスケープされていないテキストとして出力します。

<xsl:stylesheet version="1.0" 
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
          xmlns:feature="http://stackoverflow.com"
      exclude-result-prefixes="feature" >
<xsl:template match="feature:XXX">
  <xsl:variable name="p" select="substring-before(name(), ':')"/>
  <xsl:copy>
   <xsl:value-of select="concat('&lt;', $p,':Characteristic', '&gt;')" disable-output-escaping="yes"/>
   <xsl:apply-templates select="feature:Characteristics"/>
   <xsl:value-of select="concat('&lt;/', $p,':Characteristic', '&gt;')" disable-output-escaping="yes"/>
   <xsl:copy-of select="*[not(self::feature:Characteristics)]" /> 
 </xsl:copy>
</xsl:template>
  <xsl:template match="feature:Characteristics">
   <arrays:unsignedShort 
       xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
     <xsl:value-of select="." />
   </arrays:unsignedShort>
 </xsl:template>
</xsl:stylesheet>
于 2010-01-06T01:13:39.823 に答える
1

一貫した名前空間プレフィックスが必要な場合は、copy-ofではなく、新しい要素を生成する必要があります。XSLT で、名前空間プレフィックスを任意の値 (feature、h など) に設定します。

次の XSLT:

<xsl:stylesheet version="1.0"
              xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
              xmlns:feature="http://stackoverflow.com"
              xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
  <xsl:output method="xml" indent="yes" />

  <xsl:template match="feature:XXX">
   <xsl:element name="feature:XXX">
    <feature:Characteristic>
      <xsl:apply-templates select="feature:Characteristics"/>
    </feature:Characteristic>
    <xsl:apply-templates select="*[not(self::feature:Characteristics)]" />
  </xsl:element>
  </xsl:template>

  <xsl:template match="feature:Characteristics">
    <xsl:element name="arrays:unsignedShort">
        <xsl:value-of select="." />
    </xsl:element>
  </xsl:template>

  <xsl:template match="*">
     <xsl:element name="feature:{local-name()}" >
        <xsl:value-of select="." />
     </xsl:element>
  </xsl:template>

</xsl:stylesheet>

次の出力が生成されます。

<?xml version="1.0" encoding="UTF-16"?>
<feature:XXX xmlns:feature="http://stackoverflow.com">
 <feature:Characteristic xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
  <arrays:unsignedShort>7</arrays:unsignedShort>
  <arrays:unsignedShort>11</arrays:unsignedShort>
  <arrays:unsignedShort>12</arrays:unsignedShort>
 </feature:Characteristic>
 <feature:ProductName>blah</feature:ProductName>
 <feature:Vendor>blah</feature:Vendor>
 <feature:Version></feature:Version>
</feature:XXX>
于 2010-01-06T01:46:34.423 に答える