web-dev-qa-db-ja.com

XSLTを使用してXMLから名前空間を削除する方法

私は150 MBのXMLファイルを持っています(場合によってはさらに大きくなることがあります)。すべての名前空間を削除する必要があります。これはVisual Basic 6.0上にあるので、DOMを使用してXMLをロードしています。読み込みは大丈夫です。最初は懐疑的でしたが、どういうわけかその部分はうまく機能します。

私は次の [〜#〜] xslt [〜#〜] を試していますが、他のすべての属性も削除されます。すべての属性と要素を保持したいのですが、名前空間を削除するだけです。どうやら私はxsl:elementが属性ではありません。そこに属性を含めるにはどうすればよいですか?

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="UTF-8" />
    <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>
21
GaneshT

属性をコピーするテンプレートがないため、XSLTも属性を削除します。 _<xsl:template match="*">_は、要素(またはテキスト、コメント、処理命令)ではなく、要素のみに一致します。

以下は、処理されたドキュメントからすべての名前空間定義を削除し、他のすべてのノードと値(要素、属性、コメント、テキスト、処理命令)をコピーするスタイルシートです。 2つのことに注意してください

  1. このように属性をコピーするだけでは、すべての名前空間を削除することはできません。また、含まれている要素が名前空間に属していない場合でも、属性は名前空間に属することができます。したがって、要素のように属性も作成する必要があります。属性の作成は_<xsl:attribute>_要素で行われます。
  2. 有効なXMLドキュメントには、同じ拡張名を持つ2つ以上の属性を持つ要素を含めることはできませんが、要素には同じローカル名を持つ複数の属性を含めることができます属性の名前空間が異なる場合これは、名前空間プレフィックスを同じローカル名を持つ少なくとも2つの属性を持つ要素がある場合、属性名はデータ損失を引き起こします。これらの他の属性は削除(または上書き)されます。

...そしてコード:

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

    <xsl:output indent="yes" method="xml" encoding="utf-8" omit-xml-declaration="yes"/>

    <!-- Stylesheet to remove all namespaces from a document -->
    <!-- NOTE: this will lead to attribute name clash, if an element contains
        two attributes with same local name but different namespace prefix -->
    <!-- Nodes that cannot have a namespace are copied as such -->

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

    <!-- template to copy attributes -->
    <xsl:template match="@*">
        <xsl:attribute name="{local-name()}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>

    <!-- template to copy the rest of the nodes -->
    <xsl:template match="comment() | text() | processing-instruction()">
        <xsl:copy/>
    </xsl:template>

</xsl:stylesheet>
_

最後のテンプレートの代わりに<xsl:template match="node()">を使用することもできますが、priority属性を使用して、このテンプレートに一致する要素を防止する必要があります。

33
jasso

そこに属性を含めるにはどうすればよいですか?

このテンプレートを既存のテンプレートに追加するだけです。

<xsl:template match="@*">
    <xsl:copy/>
</xsl:template>
1
Emiliano Poggi