2011-06-20 9 views
2

私はAP Webfeedからコンテンツを消化しようとしていますが、いくつかの理由で非常に単純なため、各ループは私にフィットを与えているすべきか。フィードは、xsltprocessorとsimplexmlを使用してAPから送信されるxml utf-8です。XSLTなぜこの非常に基本的な選択は機能しませんか?

問題は、私は上のループに希望正しいノードをターゲットにすることはできませんということです。フィード自体は、フィードのいくつかのプロパティを持つルート要素であり、次にいくつかの「エントリ」子記事です。それらのそれぞれは、子供の属性(著作権のような)と実際のニットの内容(鉛とボディ)を持っています

私は何も得ていない。私もできません<xsl:value-of select="feed/id" /> - 奇妙なことに、私は// nitf @ versionを正しく取得するために取得できますが、フィード/エントリ/コンテンツ/ nitf/@バージョンを取得できません。

<xsl:for-each select="//nitf" >記事の本文やnitfノードの子孫を取得しますが、より上位の要素(//エントリなど)は取得しません。ただ間違っているようだ - 私は近いルートにコンテンツを取得することができる唯一の方法は、ダウンルート(フィード)と掘削始まる<xsl:for-each="/*" />を入れ子にすることです。

誰もが、私はそれを本当に感謝し、正しい方向に私を指すことができれば、一見とてもシンプルな何かが、私は今しばらく立ち往生していることを私にイライラされて。

フォーマットは次のとおりです。

<feed> 
    <id></id> 
    <published></published> 
    <entry> 
     <copyright></copyright> 
     <content> 
     <nitf> 
      <head></head> 
      <body></body> 
     </nitf> 
     </content> 
    </entry> 
    <entry> 
     <content> 
     <nitf> 
      <head></head> 
      <body></body> 
     </nitf> 
     </content> 
    </entry> 
</feed> 



<?xml version="1.0" ?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
    <xsl:template match="/"> 
     <!-- this does loop through nitf --> 
     <xsl:for-each select="descendant::*/nitf"> 
     <nitf_title></nitf_title> 
     </xsl:for-each> 

     <!-- I want to loop on these instead but this never loops --> 
     <xsl:for-each select="descendant::*/entry"> 
     <entry_title><entry_title> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

ので、私は

<?xml version="1.0" encoding="utf-8" ?> 

<feed xmlns="http://www.w3.org/2005/Atom" xmlns:apcm="http://ap.org/schemas/03/2005/apcm" xmlns:apnm="http://ap.org/schemas/03/2005/apnm" xmlns:georss="http://www.georss.org/georss"> 

    <id>urn:publicid:ap.org:31998</id>  
    <title type="xhtml">  
    <apxh:div xmlns:apxh="http://www.w3.org/1999/xhtml">  
     <apxh:span>AP Online National News</apxh:span>  
    </apxh:div>  
    </title>  
    <apcm:Property Name="FeedProperties">  
    <apcm:Property Name="Entitlement" Id="urn:publicid:ap.org:product:31998" Value="AP Online National News" />  
    <apcm:Property Name="FeedSequencing"> 
     <apcm:Property Name="sequenceNumber" Id="111835329" /> 
     <apcm:Property Name="minDateTime" Value="2011-06-20T16:56:08.047Z" />  
    </apcm:Property>  
    </apcm:Property>  
    <updated>2011-06-20T16:56:08.047Z</updated>  
    <author>  
    <name>The Associated Press</name>  
    <uri>http://www.ap.org</uri>  
    </author>  
    <rights></rights>  
    <link rel="self" href="http://syndication.ap.org" />  
<entry xmlns="http://www.w3.org/2005/Atom"> 
    <id>urn:publicid:ap.org:badf779c9d5246b5acb21430ed2214fb</id> 
    <title>APFN-US--Gas Drilling-Chemicals</title> 
    <updated>2011-06-20T16:56:08.047Z</updated> 
    <published>2011-06-20T16:25:39Z</published> 
    <author> 
    <name>AP</name> 
    </author> 
    <rights>Copyright 2011</rights> 
    <content type="text/xml"> 
    <nitf version="-//IPTC//DTD NITF 3.4//EN" change.date="October 18, 2006" change.time="19:30" xmlns=""> 
     <head> 
     <docdata> 
      <doc-id regsrc="AP" /> 
      <date.issue norm="20110620T162539Z" /> 
      <ed-msg info="Eds: APNewsNow." /> 
      <doc.rights owner="http://www.ap.org" agent="http://license.icopyright.net" type="none" /> 
      <doc.copyright holder="AP" year="2011" /> 
     </docdata> 
     </head> 
     <body> 
     <body.head> 
      <hedline> 
      <hl1 id="headline">Texas becomes 1st to require fracking disclosure</hl1> 
      <hl2 id="originalHeadline">Texas becomes 1st to require fracking disclosure</hl2> 
      </hedline> 
      <distributor>The Associated Press</distributor> 
      <dateline> 
      <location>HOUSTON</location> 
      </dateline> 
     </body.head> 
     <body.content> 
      <block id="Main"> 
       <p>HOUSTON (AP) — Texas </p> 
      </block> 
     </body.content> 
     <body.end /> 
     </body> 
    </nitf> 
    </content> 
    <apcm:ContentMetadata xmlns:apcm="http://ap.org/schemas/03/2005/apcm"> 
    <apcm:DateLineLocation City="Houston" Country="USA" CountryArea="TX" CountryAreaName="Texas" CountryName="United States" /> 
    <apcm:Priority Numeric="4" Legacy="r" /> 
    <apcm:ConsumerReady>TRUE</apcm:ConsumerReady> 
    <apcm:DateLine>HOUSTON</apcm:DateLine> 
    </apcm:ContentMetadata> 
</entry> 

<entry xmlns="http://www.w3.org/2005/Atom"> 
    <id>urn:publicid:ap.org:57582781c3a841a2b9849231a4abdb63</id> 
    <title>US--Medicare-Prevention</title> 
    <updated>2011-06-20T16:54:57.963Z</updated> 
    <published>2011-06-20T16:54:43Z</published> 
... 
+3

名前空間の問題のように聞こえます。私たちにもXSLコードを見せてください。 –

+4

通常、このような問題はXMLで使用されている名前空間で発生します。ただし、サンプルには名前空間の宣言は表示されません。実際の入力ソースを投稿してもよろしいですか?それが 'xmlns =" http://example.com/ "'(そしておそらくそれらの 'nitf'要素に' xmlns = "" ')を持っているかどうかを確認してください。 –

+0

XPathが動作しない理由と、特定の名前空間で修飾された要素を選択するようにXSLTを構成する方法に関する一般的な概念については、私の回答を参照してください。将来のユーザーのための良い参照の質問の+1。 –

答えて

2

として、以下のソースフィード、実際の例を嘲笑私は上記のコメントで指摘短いそれを維持しようとしていた申し訳ありませんが、あなたの問題ソースドキュメント内の名前空間に関連しています。たとえば、 "entry"という名前の要素を照合しようとしていますが、実際の要素の修飾名は{http://www.w3.org/2005/Atom}:entryです。

あなたは接頭辞を使用して、名前空間修飾子を含めて、適切な値にそのプレフィックスをマップするために、あなたのXPathを書き換える必要があります。結果として、「entry」は「atom:entry」になり、囲み要素の中には、xmlns:atom = "http://www.w3.org/2005/Atom"というようにatomの宣言があります。

+0

ありがとうございました。フィードソースにはいくつかの名前空間が宣言されているので、そういうものかもしれません。私は提案に従って、原子や他のap固有の要素の接頭辞を入れて、今必要なものに対処することができます。 –

2

上記のコメントとは異なり、実際にはnitf要素を選択するための名前空間宣言は必要ありません。名前空間のない要素(xmlns="")です。実際には、//を使用するだけで、文書内の任意のnitf要素を選択できます。例えば:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="xml" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="/"> 
     <xsl:copy-of select="//nitf"/> 
    </xsl:template> 

</xsl:stylesheet> 

は関係なく、名前空間親導出、出力タイプnitfのすべてのノードをコピーしません。

異なる名前空間ではなく、entryを持って、それがxmlns="http://www.w3.org/2005/Atom"です。この要素を正しく選択するには、ドキュメント内の名前空間接頭辞を宣言し、それに応じて使用する必要があります。例えば:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:atom="http://www.w3.org/2005/Atom"> 

    <xsl:output method="xml" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="/"> 
     <xsl:for-each select="//nitf"> 
      <!-- iterate on nitf children --> 
     </xsl:for-each> 

     <xsl:for-each select="//atom:entry"> 
      <!-- iterate on entry children --> 
     </xsl:for-each> 
    </xsl:template> 

</xsl:stylesheet> 

は、任意の{}:nitfの子供に最初の反復した後、任意の{http://www.w3.org/2005/Atom}:entryのそれらのだろう。


あなたの最初のXPathが最初のXPathで

が動作していない理由:あなたはどんなnitfを選択するために、軸を使用している

descendant::*/nitf 

*を使用すると、XPathはすべてnitf要素を選択し、要素の子孫はnull名前空間に選択します。しかし、ヌル名前空間の要素子孫はnitfではありません。 nitfは、http://www.w3.org/2005/Atom名前空間uriで修飾された要素の子です。

ここ軸を使用するための正しい方法は、(前の例のように)http://www.w3.org/2005/Atomの名前空間接頭辞を宣言した後、次のとおりです。

descendant::atom:*/nitf 

か、あなたはまた、低レベルを使用することができます。

(上記の最初の例に示すように)
descendant::node()/nitf 

最後に、最も簡単な方法がある:

//nitf 

最後の2つのXPathは、任意の名前空間で修飾された要素の子孫nitf要素を選択することに注意してください。だから、あなたが入力文書を絶対に知っていて、あなたが何をしているのかを知っているときにそれらを使うべきです。

関連する問題