2

次のxmlファイルがあります。

<root_tag>
<tag1>
    <tag1_1>A</tag1_1>
    <tag1_2>B</tag1_2>
    <tag1_3>C</tag1_3>
</tag1>
<tag2>
    <tag2_1>D</tag2_1>
    <tag2_2>
        <elem xmlns="http://a.b.com/sample">
            <elem_1>E</elem_1>
            <elem_2>F</elem_2>
        </elem>
    </tag2_2>
</tag2></root_tag>

および xslt テンプレート:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" version="1.0" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
    <NODE>
        <node1>
            <xsl:value-of select="/root_tag/tag1/tag1_2"/>
        </node1>
        <node2>
            <xsl:value-of select="/root_tag/tag2/tag2_1"/>
        </node2>
        <node3>
            <xsl:value-of select="/root_tag/tag2/tag2_2/child::*[local-name(.) = 'elem']/child::*[local-name(.) = 'elem_1']"/>
        </node3>
        <xsl:variable name="A" select="namespace-uri(/root_tag/tag2/tag2_2/child::*[local-name(.) = 'elem'])"/>
        <node4>    
            <xsl:value-of select="$A"/>
        </node4>
        <node5>
            <!-- some code here -->
        </node5>
    </NODE>
</xsl:template>

出力は次のとおりです。

<NODE>
    <node1>B</node1>
    <node2>D</node2>
    <node3>E</node3>
    <node4>http://a.b.com/sample</node4>
    <node5></node5>
</NODE>

node3 のような xpath を使用せずに、 node5 で/root_tag/tag2/tag2_2/elem/elem_1の値を取得する方法はありますか? elem の名前空間を格納する変数 A を何らかの形で使用できますか?

また、 xsl:stylesheetタグにxmlns:a_1="http://abcom/sample"を追加し、xpath /root_tag/tag2/tag2_2/a_1:elem/a_1:elem_1を使用して情報を抽出することもできましたが、これだけです。名前空間が事前にわかっている場合をカバーします。

4

2 に答える 2

1

XSLT 1.0 でxxx:node-set()拡張子を使用してこれを行う 1 つの方法を次に示します。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vrtfDoc2">
  <xsl:apply-templates/>
 </xsl:variable>

 <xsl:template match="/">
  <node5>
   <xsl:value-of select=
    "ext:node-set($vrtfDoc2)/root_tag/tag2/tag2_2/elem/elem_1"/>
  </node5>
 </xsl:template>

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

 <xsl:template match="@*">
  <xsl:attribute name="{name()}">
   <xsl:value-of select="."/>
  </xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

この変換が提供された XML ドキュメントに適用されると、次のようになります。

<root_tag>
    <tag1>
        <tag1_1>A</tag1_1>
        <tag1_2>B</tag1_2>
        <tag1_3>C</tag1_3>
    </tag1>
    <tag2>
        <tag2_1>D</tag2_1>
        <tag2_2>
            <elem xmlns="http://a.b.com/sample">
                <elem_1>E</elem_1>
                <elem_2>F</elem_2>
            </elem>
        </tag2_2>
    </tag2>
</root_tag>

必要な正しい結果 ( node5) が生成されます。

<node5>E</node5>

説明:

  1. これは2 パス変換です。

  2. pass1 では、ドキュメントは元のドキュメントの要素を含む RTF (結果ツリー フラグメント) に変換されますが、すべての要素は「名前空間なし」にあります。

  3. EXSLText:node-set()拡張関数を使用して、上記 1. で取得した RTF を通常のツリーに変換します。

  4. 関数への述語と参照を含まない提供された XPath 式は、local-name()上記の 3. で生成されたドキュメントに対して評価されます。

于 2012-11-02T03:03:54.287 に答える
1

残念だけど違う。より短い XPath:

/root_tag/tag2/tag2_2/*[local-name(.) = 'elem']/*[local-name(.) = 'elem_1']
于 2012-11-01T23:32:05.353 に答える