2011-06-01 73 views
1

我是XSL的新手,想要將NewML G2格式的XML轉換爲另一種XML。如何處理XSLT中的命名空間?

比如我有:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<!-- 
- Structure: NML2 SNI Text 
--> 
<!-- ========================================================= --> 
<newsMessage xmlns="http://iptc.org/std/nar/2006-10-01/" xmlns:rtr="http://www.reuters.com/ns/2003/08/content" xmlns:x="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <header> 
    <transmitId>tag:123.com,0000:newsml_N19279043:609406403</transmitId> 
    <priority>3</priority> 
    <destination>ABX</destination> 
    </header> 
    <itemSet> 
    <newsItem conformance="power" guid="tag:reuters.com,0000:newsml_N19279043" standard="NewsML-G2" standardversion="2.1" version="609406403" xml:lang="en"> 
     <itemMeta> 
     <itemClass qcode="icls:text" rtr:msgType="S"/> 
     <provider literal="reuters.com"/> 
     <versionCreated>2011-05-20T05:00:27.000Z</versionCreated> 
     </itemMeta> 
     <contentMeta> 
     <urgency>3</urgency> 
     <infoSource literal="Reuters" role="cRole:origProv"/> 
     <subject qcode="N2:BNK"/> 
     <headline>My Headline</headline> 
     <by>ABC</by> 
     </contentMeta> 
     <contentSet> 
     <inlineXML contenttype="application/xhtml+html" wordcount="881"> 
      <html xmlns="http://www.w3.org/1999/xhtml"> 
      <head> 
       <title/> 
      </head> 
      <body> 
       <p>Paragraph A</p> 
       <p>* Paragraph A</p> 
      </body> 
      </html> 
     </inlineXML> 
     </contentSet> 
    </newsItem> 
    </itemSet> 
</newsMessage> 

我想我的結果XML是這樣的:

<?xml version="1.0" encoding="UTF-8"?> 
<MyData> 
     <MyTransmitId>tag:123.com,0000:newsml_N19279043:609406403</MyTransmitId> 
     <MyHeadline>My Headline</MyHeadline> 
     <MyContent> 
      <html xmlns="http://www.w3.org/1999/xhtml"> 
      <head> 
       <title/> 
      </head> 
      <body> 
       <p>Paragraph A</p> 
       <p>* Paragraph A</p> 
      </body> 
      </html> 
     </MyContent> 
</MyData> 

我用下面的XSL出來:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ms="urn:schemas-microsoft-com:xslt"> 
    <xsl:output method="xml" indent="yes" encoding="utf-8" /> 
    <xsl:template match="/newsMessage"> 
    <MyTransmitId> 
     <xsl:value-of select="header/transmitId"/> 
     </MyTransmitId> 
    <MyHeadline> 
     <xsl:value-of select="itemSet/newsItem/contentMeta/headline"/> 
    </MyHeadline> 
    <MyContent> 
     <xsl:value-of select="itemSet/newsItem/contentSet/inlineXML"/> 
    </MyContent> 
    </xsl:template> 
</xsl:stylesheet> 

然而它轉化爲不太正確的東西。而且我注意到它是因爲該元素

<newsMessage xmlns="http://iptc.org/std/nar/2006-10-01/" xmlns:rtr="http://www.reuters.com/ns/2003/08/content" xmlns:x="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 

的。如果我將其更改爲以下,然後我的XSL將工作:

<newsMessage> 

如何轉變元素newsMessage用正確的命名空間?

非常感謝。

+0

我編輯了標題,使其多了幾分搜索友好。如果你喜歡舊的,請隨時回滾編輯:) – 2011-06-01 07:54:47

+0

@Merlyn:謝謝! – 2011-06-01 08:09:37

回答

1

聲明命名空間並使用它。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ms="urn:schemas-microsoft-com:xslt" xmlns:nar="http://iptc.org/std/nar/2006-10-01/"> 
... 
    <xsl:template match="/nar:newsMessage"> 
    ... 
+0

謝謝。那是聲明第一個命名空間,我如何指定第二個名稱空間是xmlns:rtr =「http://www.reuters.com/ns/2003/08/content」?我嘗試了一個名稱空間,並得到結果:'<?xml version =「1.0」encoding =「utf-8」?> 2011-06-01 08:14:04

+0

只需將其添加並以完全相同的方式使用它即可。 – 2011-06-01 08:16:51

+0

聲明它們並使用它:? – 2011-06-01 08:20:11

3

一對夫婦的問題在這裏:

首先,多源文件在命名空間命名爲「http://iptc.org/std/nar/2006-10-01/」並且在XSLT中引用該內容時需要考慮這一點。在下面的樣式表中,我通過將此名稱空間綁定到前綴「itpc」,然後在XPath表達式中使用它來完成此操作。

其次,你想要的XHTML內容結構被複制到你的結果,你需要使用< XSL:複製的>(沒有價值的),這樣做—其實你需要得到內容你的inlineXML元素的,而不是它本身;我相應地修改了XPath。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:itpc="http://iptc.org/std/nar/2006-10-01/"> 
    <xsl:output method="xml" indent="yes" encoding="utf-8"/> 
    <xsl:template match="/itpc:newsMessage"> 
     <MyTransmitId> 
      <xsl:value-of 
       select="itpc:header/itpc:transmitId"/> 
     </MyTransmitId> 
     <MyHeadline> 
      <xsl:value-of 
       select="itpc:itemSet/itpc:newsItem/itpc:contentMeta/itpc:headline"/> 
     </MyHeadline> 
     <MyContent> 
      <xsl:copy-of 
       select="itpc:itemSet/itpc:newsItem/itpc:contentSet/itpc:inlineXML/*"/> 
     </MyContent> 
    </xsl:template> 
</xsl:stylesheet>
+0

這正是我想要的!你給我提供的不僅僅是答案,還有許多新的信息對我來說是有意義的!謝謝! – 2011-06-01 08:22:21

0

我發現了另一個解決這一之一,在這裏發帖對他人的好處:)

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" media-type="text/html"/> 
    <xsl:template match="/"> 
     <xsl:element name="MyData"> 
      <xsl:element name="MyTransmitId"> 
       <xsl:value-of select="//*[name()='transmitId']"/> 
      </xsl:element> 
      <xsl:element name="MyHeadline"> 
       <xsl:value-of select="//*[name()='headline']"/> 
      </xsl:element> 
      <xsl:element name="MyContent"> 
       <xsl:copy-of select="//*[name()='inlineXML']/*"/> 
      </xsl:element> 
     </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 
+0

除了這是一個非常脆弱的方法,它依賴於源文檔的名稱空間,每次都以相同的方式詞法記錄。如果由於某種原因使用了前綴,樣式表將失敗。你可以通過使用local-name()而不是name()來防止這種情況發生。 – alexbrn 2011-06-03 07:14:13