最近、任意の XML をネストされた順序なしリストとして表される HTML ツリー ビューに変換する XSLT を実装しました。この XSLT の簡易バージョンを次に示します。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="no"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates select="." mode="render"/>
</body>
</html>
</xsl:template>
<xsl:template match="/" mode="render">
<div>
<ul>
<xsl:apply-templates mode="render"/>
</ul>
</div>
</xsl:template>
<xsl:template match="*" mode="render">
<li>
<span>
<xsl:value-of select="local-name()"/>
</span>
<div>
<xsl:if test="./text()">
<span>
<xsl:value-of select="translate(./text(),' ',' ')"/>
</span>
</xsl:if>
<xsl:if test="count(child::*)>0 or count(attribute::*)>0">
<ul>
<xsl:apply-templates select="@*" mode="render"/>
<xsl:apply-templates select ="*" mode="render"/>
</ul>
</xsl:if>
</div>
</li>
</xsl:template>
<xsl:template match="@*" mode="render">
<li>
<span>
<xsl:value-of select="local-name()"/>
</span>
<div>
<span>
<xsl:value-of select="translate(.,' ',' ')"/>
</span>
</div>
</li>
</xsl:template>
</xsl:stylesheet>
この XSLT は XML スキーマに依存しないことに注意してください。したがって、任意の XML に適用できます。たとえば、与えられた入力 XML
<Catalog xmlns="somenamespace">
<CatalogName>First catalog</CatalogName>
<Products>
<Product id="p1">
<Name>Some product</Name>
<Description>foo</Description>
</Product>
<Product id="p2">
<Name>Another product</Name>
<Description>bar</Description>
</Product>
</Products>
</Catalog>
目的のツリー ビューを作成します
<html>
<body>
<div>
<ul>
<li>
<span>Catalog</span>
<div>
<ul>
<li>
<span>CatalogName</span>
<div>
<span>First catalog</span>
</div>
</li>
<li>
<span>Products</span>
<div>
<ul>
<li>
<span>Product</span>
<div>
<ul>
<li>
<span>id</span>
<div>
<span>p1</span>
</div>
</li>
<li>
<span>Name</span>
<div>
<span>Some product</span>
</div>
</li>
<li>
<span>Description</span>
<div>
<span>foo</span>
</div>
</li>
</ul>
</div>
</li>
<li>
<span>Product</span>
<div>
<ul>
<li>
<span>id</span>
<div>
<span>p2</span>
</div>
</li>
<li>
<span>Name</span>
<div>
<span>Another product</span>
</div>
</li>
<li>
<span>Description</span>
<div>
<span>bar</span>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</body>
</html>
問題は、入力 XMl の構造が変更されていることです。実際、これは何らかのルート ノード内にラップされた XML ドキュメントのコレクションのように見えます。以下の例を参照してください。
<Catalogs xmlns="somenamespace">
<Catalog>
<CatalogName>First catalog</CatalogName>
<Products>
<Product id="p1.1">
<Name>Some product</Name>
<Description>foo</Description>
</Product>
<Product id="p1.2">
<Name>Another product</Name>
<Description>bar</Description>
</Product>
</Products>
</Catalog>
<Catalog>
<CatalogName>Second catalog</CatalogName>
<Products>
<Product id="p2.1">
<Name>Some product</Name>
<Description>hoho</Description>
</Product>
<Product id="p2.2">
<Name>Strange product</Name>
<Description>bar</Description>
</Product>
</Products>
</Catalog>
...
</Catalogs>
要件は、すべての異なる値がコンマで連結された「マージされた」コレクションのツリーとして出力を表示する必要があることです。目的の出力を参照してください。
<html>
<body>
<div>
<ul>
<li>
<span>Catalog</span>
<div>
<ul>
<li>
<span>CatalogName</span>
<div>
<span>First catalog, Second catalog</span>
</div>
</li>
<li>
<span>Products</span>
<div>
<ul>
<li>
<span>Product</span>
<div>
<ul>
<li>
<span>id</span>
<div>
<span>p1.1, p2.1</span>
</div>
</li>
<li>
<span>Name</span>
<div>
<span>Some product</span>
</div>
</li>
<li>
<span>Description</span>
<div>
<span>foo, hoho</span>
</div>
</li>
</ul>
</div>
</li>
<li>
<span>Product</span>
<div>
<ul>
<li>
<span>id</span>
<div>
<span>p1.2, p2.2</span>
</div>
</li>
<li>
<span>Name</span>
<div>
<span>Another product, Strange product</span>
</div>
</li>
<li>
<span>Description</span>
<div>
<span>bar</span>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</body>
</html>
XSLT は依然として「スキーマフリー」でなければならないことに注意してください。 私はこの問題で立ち往生しています。私が見る唯一の解決策は、msxsl:scriptを使用することです。ただし、この場合、XSLT はアプリケーションの外では機能しない可能性があるため、望ましくありません。
何か案は?