2012-01-10 18 views
1

XQUERYを使用して、次のXMLから属性filenameを取得できますか?時にはfilename属性は、属性@filename OR @fileNameから値を取得するために、着信XML..thinkingにfileNameとして送信されます...XQUERYを使用して属性値を取得する

<?xml version="1.0"?> 
<preFileDoc xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"> 
    <senderId>ABC</senderId> 
    <receiverId>XYZ</receiverId> 
    <tranxCode>A001</tranxCode> 
    <inpXML version="1.0" encoding="UTF-8"> 
    <soap-env:Envelope> 
     <soap-env:Header msgcode="SPPCONVAKT" orig-system="002FTB" refid="65355ff50a172064484bf9da64c1e245" timestamp="2009-02-11 21:00:10.741" filename="SPPCONVAKT20090128001.dat"/> 
     <soap-env:Body> 
text1 
text2 
     </soap-env:Body> 
    </soap-env:Envelope> 
    </inpXML> 
</preFileDoc> 

psのを私は/preFileDoc/inpXML/@filenameを使用しようとしていますが、それは動作しません。それは単一のXQUERYで達成できますか?アドバイスありがとうございます...

+0

こんにちはmarc_s ..itは、特定のxmlノードの値をクエリするためのxqueryをサポートするいくつかの開発プラットフォーム上にあります。 – user1140422

答えて

0

SOAP XML名前空間を尊重して考慮する必要があります。

私はあなたが使用しているかわからないので、私はこれを行う方法を伝えることはできません - しかし、xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"は、ルートノードにあります、そして、あなたの@filename属性が<soap-env:Header .... />ノード上で - あなたはインクルードする必要がありXQueryのXML名前空間。

.NET/C#では、あなたは(直接のXPathをサポートしています「古い」XmlDocumentスタイルを使用して)このようにそれを行うことができます:

// define test XML 
string xmlContent = 
    @"<?xml version='1.0'?> 
    <preFileDoc xmlns:soap-env='http://schemas.xmlsoap.org/soap/envelope/'> 
     <senderId>ABC</senderId> 
     <receiverId>XYZ</receiverId> 
     <tranxCode>A001</tranxCode> 
     <inpXML version='1.0' encoding='UTF-8'> 
      <soap-env:Envelope> 
       <soap-env:Header msgcode='SPPCONVAKT' orig-system='002FTB' refid='65355ff50a172064484bf9da64c1e245' timestamp='2009-02-11 21:00:10.741' filename='SPPCONVAKT20090128001.dat'/> 
       <soap-env:Body> 
       text1 
       text2 
       </soap-env:Body> 
      </soap-env:Envelope> 
     </inpXML> 
    </preFileDoc>"; 

// create XmlDocument and load test data 
XmlDocument doc = new XmlDocument(); 
doc.LoadXml(xmlContent); 

// define XML namespace manager and add the SOAP namespace to it 
XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable); 
mgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/"); 

// use XPath and the XML namespaces to grab the <Header> node 
// the first two nodes <preFileDoc> and <inpXML> are not inside any explicit 
// XML namespace 
// but the next two (<Envelope> and <Header>) are in the "soap" XML namespace 
XmlNode header = doc.SelectSingleNode("/preFileDoc/inpXML/soap:Envelope/soap:Header", mgr); 

// read the "filename" attribute from the header node 
if(header != null && header.Attributes["filename"] != null) 
{ 
    string fileName = header.Attributes["filename"].Value; 
} 
+0

こんにちはmarc_s..yourは、.NET/C#でソリューション全体を提供してくれてとても親切です。Envelope/soap-env:Header/@ filename |/preFileDoc/inpXML/soap-env:Envelope/soapここでは、以下のXQUERYで以下のステートメントで必要なものを取得しています。 -env:Header/@ fileName – user1140422

1

あなたは複数の属性の和集合を取ることができます。それはそれは、常に単一のノードを返す必要がありますので、この属性は、異なる筐体で複数回出現する可能性は低いだろう。

//soap-env:Header/@filename | //soap-env:Header/@fileName 

オプションを、あなたは括弧でそれをラップし、その背後に[1]を追加し、常に取ることができ最初の結果。

(//soap-env:Header/@filename | //soap-env:Header/@fileName)[1] 

あなたが代わりに文書順序ノードセットのシーケンスを作成し、カンマ、で労働組合を交換する場合は、最後に、同様のデフォルトを追加することができます。ここではあまり役に立たないかもしれませんが、おそらく他の状況では:

(//soap-env:Header/@filename , //soap-env:Header/@fileName, "default.dat")[1] 

HTH!

+0

ありがとうございましたgrtjn ...はい私は、ユニオンの複数の属性の解決に必要なものを絶対に:) – user1140422

1

あなたのXPathは不完全だと思います。最後の子ステップ//preFileDoc/inpXML/@filenameは、その子孫ではなくinpXML要素の属性と一致します。これは、あまりにも、soapenv:Bodyfilenameという名前のすべての属性を見つけるだろうと

/preFileDoc/inpXML//@filename 

注:この問題を解決するために

一つの方法は、// -stepだろう。

より堅牢な方法は、このようにXQueryでsoapenv接頭辞を宣言するために、次のようになります。

declare namespace soap-env="http://schemas.xmlsoap.org/soap/envelope/"; 

return /preFileDoc/inpXML//soap-env:Header/@filename 

は最後に、filenameの異なる総額は、両方を指定することで回避することができます。

declare namespace soap-env="http://schemas.xmlsoap.org/soap/envelope/"; 

return /preFileDoc/inpXML//soap-env:Header/(@filename | @fileName) 
関連する問題