-1

Oracle Database 10g Enterprise Edition リリース 10.2.0.5 - 64bi

見つけた要素から、祖先または自己を使用してルートに階層を出力しようとしていますが、まったく機能しません。すべての要素を出力するだけです(

さて、私が持っているもの:

1) このような XML ファイル。

<Root>
  <Element1 id="UniqueId1">
    <SubElement1 id="UniqueId2"/>
    <SubElement2 id="UniqueId3">
      <LeafElement1 id="UniqueId4"/>
      <LeafElement1 id="UniqueId5"/>
    </SubElement2>
  </Element1>
  <Element2 id="UniqueId6" AttributeToCheck="true">
    <SubElement1 id="UniqueId7">
      <LeafElement1 id="UniqueId8"/>
      <LeafElement1 id="UniqueId9"/>
    </SubElement1>
  </Element2> 
</Root>

2) 私の XPATH 文字列:

//*[@id and contains(@id, "UniqueId8")]/ancestor-or-self::*

3) 次のような結果を取得したい (見つかった要素からルートまで):

<Root>
  <Element2 id="UniqueId6" AttributeToCheck="true">
    <SubElement1 id="UniqueId7">
      <LeafElement1 id="UniqueId8"/>
    </SubElement1>
  </Element2> 
</Root>

ところで、 // [@id and contains(@id, "UniqueId8")]/ancestor-or-self:: /@id は問題なく動作します。

この問題を解決する方法を知っている人はいますか、それとも祖先または自己の代わりに別の操作を使用するだけですか?

アップデート:

私はこれを実行します:

DECLARE
  v_xml XMLTYPE;
BEGIN
    SELECT xmltype('<Root>
               <Element1 id="UniqueId1">
            <SubElement1 id="UniqueId2"/>                                           <SubElement2 id="UniqueId3">
                                            <LeafElement1 id="UniqueId4"/>
                                            <LeafElement1 id="UniqueId5"/>
                                        </SubElement2>
                                    </Element1>
                                    <Element2 id="UniqueId6" AttributeToCheck="true">
                                        <SubElement1 id="UniqueId7">
                                            <LeafElement1 id="UniqueId8"/>
                                            <LeafElement1 id="UniqueId9"/>
                                        </SubElement1>
                                    </Element2>
                                </Root>')
    into v_xml
    from dual;

    select extract(v_xml, '//*[@id="UniqueId9"]/ancestor-or-self::*')
    into v_xml
    from dual;

    dbms_output.put_line(v_xml.getStringVal());

END;

しかし、結果として、私は何か奇妙なものを得ました:

<Root>
  <Element1 id="UniqueId1">
              <SubElement1 id="UniqueId2"/>
            <SubElement2 id="UniqueId3">
                                     <LeafElement1 id="UniqueId4"/>
                                                 <LeafElement1 id="UniqueId5"/>
     </SubElement2>
    </Element1>
    <Element2 id="UniqueId6" AttributeToCheck="true">
    <SubElement1 id="UniqueId7">
    <LeafElement1 id="UniqueId8"/>
    <LeafElement1 id="UniqueId9"/>
    </SubElement1></Element2>
</Root>
<Element2 id="UniqueId6" AttributeToCheck="true">
    <SubElement1 id="UniqueId7">
        <LeafElement1 id="UniqueId8"/>
        <LeafElement1 id="UniqueId9"/>
    </SubElement1>
</Element2>

<SubElement1 id="UniqueId7">
    <LeafElement1 id="UniqueId8"/>
    <LeafElement1 id="UniqueId9"/>
</SubElement1>

<LeafElement1 id="UniqueId9"/>
4

4 に答える 4

2

XPath では、入力ドキュメント内のノードを選択することしかできません。ドキュメントの構造を変更したり、ノードを変更 (追加、削除、操作) した新しいドキュメントを作成したりすることはできません。したがって、パス式でルート要素を選択して結果を出力すると、もちろんルート要素とそれに含まれるすべてのノードが出力されます。

したがって、XPath ではやりたいことを実行できません。そのためには、XQuery または XSLT を使用する必要があります。そうすれば、削除したくないノードを含む新しいドキュメントを作成できます。祖先ノードの詳細を含む xhtml ファイルを分離するフラグメント入力 xhtmlは、特定のノードの祖先または子ではないルート要素の子孫ノードを除外するために XSLT が使用されるサンプルです。いくつかのノードに対して必要以上のことを行い、いくつかの結果ドキュメントを作成しますが、コードの一部は必要なことを行っています。ただし、XSLT をまったく使用できるのか、それとも Oracle のコンテキストで XSLT 2.0 を使用できるのかはわかりません。そのため、XSLT を使用できることと使用できる XSLT のバージョンを明確に示さない限り、そのコードを入力サンプルに適合させようとはしません。 Oracle のコンテキストで使用します。

于 2012-11-13T10:15:09.187 に答える
2

Martin が言うように、XPath を使用して、入力に存在しないツリーを構築することはできません。

さらなるポイント: XPath 式がノードを選択することに注意してください。入力ドキュメント内のノードへのポインターのセットを返すと考えてください。XPath クエリを実行するクライアント環境では、ノードをルートとするサブツリーを表示することで、これらのノードを表示するのが一般的です。しかし、XPath 式はツリー全体を選択するのではなく、ルートのみを選択するので、ノードの下にサブツリーが表示されるので混乱するかもしれません。

于 2012-11-13T10:27:56.513 に答える
1

この XSL アプローチを試してください。

SQL> with xml as (select xmltype('<Root>
  2    <Element1 id="UniqueId1">
  3      <SubElement1 id="UniqueId2"/>
  4      <SubElement2 id="UniqueId3">
  5        <LeafElement1 id="UniqueId4"/>
  6        <LeafElement1 id="UniqueId5"/>
  7      </SubElement2>
  8    </Element1>
  9    <Element2 id="UniqueId6" AttributeToCheck="true">
 10      <SubElement1 id="UniqueId7">
 11        <LeafElement1 id="UniqueId8"/>
 12        <LeafElement1 id="UniqueId9"/>
 13      </SubElement1>
 14    </Element2>
 15  </Root>') xml from dual),
 16  xsl as (select xmltype('
 17  <xsl:stylesheet version="1.0"
 18   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 19   <xsl:template match="node()|@*">
 20    <xsl:copy>
 21     <xsl:apply-templates select="*[descendant-or-self::*[contains(@id,''UniqueId8'')]]|@*"/>
 22    </xsl:copy>
 23   </xsl:template>
 24  </xsl:stylesheet>') xsl from dual)
 25  select xm.xml.transform(xs.xsl)
 26    from xml xm, xsl xs;

XM.XML.TRANSFORM(XS.XSL)
--------------------------------------------------------------------------------

<Root>
 <Element2 id="UniqueId6" AttributeToCheck="true">
  <SubElement1 id="UniqueId7">
   <LeafElement1 id="UniqueId8">
   </LeafElement1>
  </SubElement1>
 </Element2>
</Root>
于 2012-11-13T10:52:11.423 に答える
0

nick xtenderを持つ Guy は、XPATH で優れたソリューションを見つけ、実際に機能します。

   with t_xml as ( select xmltype('
    <Root>
      <Element1 id="UniqueId1">
        <SubElement1 id="UniqueId2"/>
        <SubElement2 id="UniqueId3">
          <LeafElement1 id="UniqueId4"/>
          <LeafElement1 id="UniqueId5"/>
        </SubElement2>
      </Element1>
      <Element2 id="UniqueId6" AttributeToCheck="true">
        <SubElement1 id="UniqueId7">
          <LeafElement1 id2="UniqueId8"/>
          <LeafElement1 id="UniqueId9"/>
        </SubElement1>
      </Element2> 
    </Root>') x from dual)
    select 
       t_xml.*
      ,updatexml(x,'//*[not (descendant-or-self::*[@id2="UniqueId8"])]',chr(10)) upd
    from t_xml
于 2012-11-13T12:41:12.943 に答える