1

私は2つの異なるタイプのXMLドキュメントを持っています(1つはともう1つはa.xmlですb.xml)。ドキュメントa.xmlは、クエリを実行する必要があるメインのソースドキュメントです。ドキュメントb.xmlには、からレコードをフェッチするためのすべての可能な情報が含まれていますa.xml

ドキュメント:«a.xml»

<rs>
    <r id="r1">
        <f0>typeA</f0>
        <f1>contains value1, value2 and value3</f1>
    </r>
    <r id="r2">
        <f0>typeB</f0>
        <f1>contains value4 and value7</f1>
    </r>
    <r id="r3">
        <f0>typeA</f0>
        <f1>contains value2 and value5</f1>
    </r>
    <r id="r4">
        <f0>typeC</f0>
        <f1>contains value1 and value6</f1>
    </r>
    <r id="r5">
        <f0>typeA</f0>
        <f1>contains value5</f1>
    </r>
    <r id="r6">
        <f0>typeC</f0>
        <f1>contains value1, value2 and value3</f1>
    </r>
</rs>

ドキュメント:«b.xml»

<?xml version="1.0"?>
<qs>
    <q id="q1">
        <i0>typeA</i0>
        <i1>value1|value2|value3</i1>
        <i2>value18|value35</i2>
        <i3>value1|value7</i3>
    </q>
    <q id="q2">
        <i0>typeB</i0>
        <i1>value2|value7</i1>
        <i2>value9|value20</i2>
        <i3>value4</i3>
    </q>
</qs>

ここで、Documentに格納されるXPath selector stringsの値に基づいて動的を生成するのが好きです。そしてそれは次のようになります: b.xmlc.xml

書類c.xml

<xps>
    <xp id="q1">
        <t1>/rs/r[contains(f0,'typeA') 
                and contains(f1,'value1') 
                and contains(f1,'value2') 
                and contains(f1,'value3')]</t1>
        <t2>/rs/r[contains(f0,'typeA') 
                and contains(f1,'value18') 
                and contains(f1,'value35')]</t2>
        <t3>/rs/r[contains(f0,'typeA') 
                and contains(f1,'value1') 
                and contains(f1,'value7')]</t3>
    </xp>
    <xp id="q2">
        <t1>/rs/r[contains(f0,'typeB') 
                and contains(f1,'value2') 
                and contains(f1,'value7')]</t1>
        <t2>/rs/r[contains(f0,'typeA') 
                and contains(f1,'value9') 
                and contains(f1,'value20')]</t2>
        <t3>/rs/r[contains(f0,'typeA') 
                and contains(f1,'value4')]</t3>
    </xp>
</xps>

ここに誰かが何か考えを持っているなら、XSLTバージョン1.0でその仕事をする方法。前もって感謝します。

4

2 に答える 2

1

XSLT1.0のソリューションは次のとおりです。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" encoding="utf-8" indent="yes"/>

    <xsl:template match="@*|text()" />

    <xsl:template match="/">
        <xps>
            <xsl:apply-templates/>
        </xps>
    </xsl:template>

    <xsl:template match="q">
        <xp id="{@id}">
            <xsl:apply-templates/>
        </xp>
    </xsl:template>

    <xsl:template match="*[starts-with(name(), 'i')][not(self::i0)]">
        <xsl:element name="t{substring-after(name(), 'i')}">
            <xsl:text>/rs/r[contains(f0, '</xsl:text>
            <xsl:value-of select="preceding-sibling::i0"/>
            <xsl:text>')</xsl:text>
            <xsl:call-template name="more-conditions">
                <xsl:with-param name="list" select="."/>
            </xsl:call-template>
            <xsl:text>]</xsl:text>
        </xsl:element>
    </xsl:template>

    <xsl:template name="more-conditions">
        <xsl:param name="list"/>
        <xsl:param name="delimiter" select="'|'"/>

        <xsl:choose>
            <xsl:when test="contains($list, $delimiter)">
                <xsl:call-template name="more-conditions">
                    <xsl:with-param name="list" select="substring-before($list, $delimiter)"/>
                </xsl:call-template>
                <xsl:call-template name="more-conditions">
                    <xsl:with-param name="list" select="substring-after($list, $delimiter)"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text> and contains(f1, '</xsl:text>
                <xsl:value-of select="$list"/>
                <xsl:text>')</xsl:text>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

入力ドキュメントに適用すると、次の出力が生成されます。

<xps>
    <xp id="q1">
        <t1>/rs/r[contains(f0, 'typeA') and contains(f1, 'value1') and contains(f1, 'value2') and contains(f1, 'value3')]</t1>
        <t2>/rs/r[contains(f0, 'typeA') and contains(f1, 'value18') and contains(f1, 'value35')]</t2>
        <t3>/rs/r[contains(f0, 'typeA') and contains(f1, 'value1') and contains(f1, 'value7')]</t3>
    </xp>
    <xp id="q2">
        <t1>/rs/r[contains(f0, 'typeB') and contains(f1, 'value2') and contains(f1, 'value7')]</t1>
        <t2>/rs/r[contains(f0, 'typeB') and contains(f1, 'value9') and contains(f1, 'value20')]</t2>
        <t3>/rs/r[contains(f0, 'typeB') and contains(f1, 'value4')]</t3>
    </xp>
</xps>

空白をいくつか追加しました。必要に応じて変換を変更できますが、これで開始できます。

于 2012-04-27T05:57:23.040 に答える
0

xsltバージョン1では、変数をxpathセレクターとして使用することはできませんが、このタスクを実行する方法は他にもある可能性があります。あなたが意図した解決策ではなく問題のアイデアを提供する場合、人々は助けることができるかもしれません:)

于 2012-04-26T13:58:23.343 に答える