2010-08-17 81 views
15

我使用XSLT從一個XML標準轉換爲另一個XML標準。特定的XML標準包含一個作爲命名空間的一部分的根元素和作爲另一個命名空間的一部分的子節點。XSLT空白xmlns =「」變換後

轉換成功地反映了這些名稱空間,但子女的孩子現在包含空白的xmlns屬性。我怎樣才能防止這個xmlns =「」???

XSLT片段:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" 
> 

    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="@* | node()"> 
    <xsl:apply-templates select="REQUEST_GROUP" /> 
    </xsl:template> 

    <xsl:template match="REQUEST_GROUP"> 
    <ONCORE_ERECORD xmlns="http://test.com"> 
     <xsl:apply-templates select="REQUEST/PRIA_REQUEST/PACKAGE"/> 
     <PAYMENT PaymentType="ACH" /> 
    <TRANSACTION_INFO _AgentKey="" _AgentPassword="" /> 
    </ONCORE_ERECORD> 
</xsl:template> 

    <xsl:template match="PACKAGE"> 
    <DOCUMENT_RECORDATION xmlns="http://test2.org"> 
     <xsl:apply-templates select="PRIA_DOCUMENT"/> 
    </DOCUMENT_RECORDATION> 
    </xsl:template> 

    <xsl:template match="PRIA_DOCUMENT"> 
    <PRIA_DOCUMENT _PRIAVersion="1.2"> 
     <xsl:attribute name="_Type"> 
     <xsl:value-of select="@RecordableDocumentType"/> 
     </xsl:attribute> 
     <xsl:attribute name="_Code"/> 

    <xsl:apply-templates select="GRANTOR" /> 
    <xsl:apply-templates select="GRANTEE" /> 
    <xsl:choose> 
    <xsl:when test="count(PROPERTY) = 0"> 
     <PROPERTY> 
     <xsl:attribute name="_StreetAddress"> 
      <xsl:value-of select="@StreetAddress"/> 
     </xsl:attribute> 
     <xsl:attribute name="_StreetAddress2"> 
      <xsl:value-of select="@StreetAddress2"/> 
     </xsl:attribute> 
     <xsl:attribute name="_City"> 
      <xsl:value-of select="@City"/> 
     </xsl:attribute> 
     <xsl:attribute name="_State"> 
      <xsl:value-of select="@State"/> 
     </xsl:attribute> 
     <xsl:attribute name="_PostalCode"> 
      <xsl:value-of select="@PostalCode"/> 
     </xsl:attribute> 
     <xsl:attribute name="_County"> 
      <xsl:value-of select="@County"/> 
     </xsl:attribute> 
     <xsl:apply-templates select="LEGAL_DESCRIPTION"/> 
     </PROPERTY> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:apply-templates select="PROPERTY" /> 
    </xsl:otherwise> 
    </xsl:choose> 
    <xsl:choose> 
    <xsl:when test="count(PARTIES) = 0"> 
     <PARTIES> 
     <_RETURN_TO_PARTY _UnparsedName="" _StreetAddress="" _StreetAddress2="" _City="" _State="" _PostalCode="" /> 
     </PARTIES> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:apply-templates select="PARTIES" /> 
    </xsl:otherwise> 
    </xsl:choose> 
    <xsl:apply-templates select="EXECUTION" /> 
    <xsl:apply-templates select="CONSIDERATION" /> 
    <xsl:apply-templates select="RECORDABLE_DOCUMENT/_ASSOCIATED_DOCUMENT" /> 
    <xsl:apply-templates select="EMBEDDED_FILE" /> 
</PRIA_DOCUMENT> 

源XML:

<REQUEST_GROUP PRIAVersionIdentifier="2.4"> 
    <REQUEST> 
    <PRIA_REQUEST _Type="RecordDocuments"> 
     <PACKAGE> 
     <PRIA_DOCUMENT PRIAVersionIdentifier="2.4" RecordableDocumentSequenceIdentifier="1" RecordableDocumentType="Mortgage"> 

生成的XML:

<?xml version="1.0" encoding="utf-8"?> 
<ONCORE_ERECORD xmlns="http://test.com"> 
    <DOCUMENT_RECORDATION xmlns="http://test2.org"> 
    <PRIA_DOCUMENT _PRIAVersion="1.2" _Type="Mortgage" _Code="" xmlns=""> 
+0

你能不能,請提供(最小的),XML在其XSLT樣式表生成系統提供的結果文件? – 2010-08-17 17:56:49

+0

我在上面添加了請求的XML作爲「源XML:」 – alan 2010-08-17 18:06:42

+0

我昨天已經回答了幾乎相同的問題:**請參閱我的答案** [這個問題](http://stackoverflow.com/questions/3490246/問題與 - 添加-的xmlns屬性到XML文檔-使用-XSL)**。 – 2010-08-17 17:11:46

回答

5

我發現了一個可行的解決方案,儘管它可能不是實現預期結果的最有效方法。

我只是改變了所有文字元素的聲明來:

</xsl:element> 

,並宣佈該命名空間。生成的xslt如下:

<xsl:template match="REQUEST_GROUP"> 
<xsl:element name="ONCORE_ERECORD" namespace="http://test.com"> 
    <xsl:apply-templates select="REQUEST/PRIA_REQUEST/PACKAGE"/> 
    <xsl:element name="PAYMENT" namespace="http://test.com"> 
    <xsl:attribute name="PaymentType"> 
     <xsl:value-of select="'ACH'"/> 
    </xsl:attribute> 
    </xsl:element> 
    <xsl:element name="TRANSACTION_INFO" namespace="http://test.com"> 
    <xsl:attribute name="_AgentKey"> 
     <xsl:value-of select="''"/> 
    </xsl:attribute> 
    <xsl:attribute name="_AgentPassword"> 
     <xsl:value-of select="''"/> 
    </xsl:attribute> 
    </xsl:element> 
</xsl:element> 
    </xsl:template> 

    <xsl:template match="PACKAGE"> 
<xsl:element name="DOCUMENT_RECORDATION" namespace="http://test2.org"> 
    <xsl:apply-templates select="PRIA_DOCUMENT"/> 
</xsl:element> 
    </xsl:template> 

    <xsl:template match="PRIA_DOCUMENT"> 
<xsl:element name="PRIA_DOCUMENT" namespace="http://test2.org"> 
    <xsl:attribute name="_PRIAVersion"> 
    <xsl:value-of select="'1.2'"/> 
    </xsl:attribute> 
    <xsl:attribute name="_Type"> 
    <xsl:value-of select="@RecordableDocumentType"/> 
    </xsl:attribute> 
    <xsl:attribute name="_Code"/> 

    <xsl:apply-templates select="GRANTOR" /> 
    <xsl:apply-templates select="GRANTEE" /> 
    <xsl:choose> 
    <xsl:when test="count(PROPERTY) = 0"> 
     <xsl:element name="PROPERTY" namespace="http://test2.org"> 
      <xsl:attribute name="_StreetAddress"> 
      <xsl:value-of select="@StreetAddress"/> 
      </xsl:attribute> 
      <xsl:attribute name="_StreetAddress2"> 
      <xsl:value-of select="@StreetAddress2"/> 
      </xsl:attribute> 
      <xsl:attribute name="_City"> 
      <xsl:value-of select="@City"/> 
      </xsl:attribute> 
      <xsl:attribute name="_State"> 
      <xsl:value-of select="@State"/> 
      </xsl:attribute> 
      <xsl:attribute name="_PostalCode"> 
      <xsl:value-of select="@PostalCode"/> 
      </xsl:attribute> 
      <xsl:attribute name="_County"> 
      <xsl:value-of select="@County"/> 
      </xsl:attribute> 
      <xsl:apply-templates select="LEGAL_DESCRIPTION"/> 
     </xsl:element> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:apply-templates select="PROPERTY" /> 
    </xsl:otherwise> 
    </xsl:choose> 
    <xsl:choose> 
    <xsl:when test="count(PARTIES) = 0"> 
     <xsl:element name="PARTIES" namespace="http://test2.org"> 
     <xsl:element name="_RETURN_TO_PARTY" namespace="http://test2.org"> 
      <xsl:attribute name="_UnparseName"> 
      <xsl:value-of select="''"/> 
      </xsl:attribute> 
      <xsl:attribute name="_StreetAddress"> 
      <xsl:value-of select="''"/> 
      </xsl:attribute> 
      <xsl:attribute name="_StreetAddress2"> 
      <xsl:value-of select="''"/> 
      </xsl:attribute> 
      <xsl:attribute name="_City"> 
      <xsl:value-of select="''"/> 
      </xsl:attribute> 
      <xsl:attribute name="_State"> 
      <xsl:value-of select="''"/> 
      </xsl:attribute> 
      <xsl:attribute name="_PostalCode"> 
      <xsl:value-of select="''"/> 
      </xsl:attribute> 
     </xsl:element> 
     </xsl:element> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:apply-templates select="PARTIES" /> 
    </xsl:otherwise> 
    </xsl:choose> 
    <xsl:apply-templates select="EXECUTION" /> 
    <xsl:apply-templates select="CONSIDERATION" /> 
    <xsl:apply-templates select="RECORDABLE_DOCUMENT/_ASSOCIATED_DOCUMENT" /> 
    <xsl:apply-templates select="EMBEDDED_FILE" /> 
    </xsl:element> 
    </xsl:template> 
6

發生這種情況,因爲PRIA_DOCUMENT是默認的命名空間,而它的pa租DOCUMENT_RECORDATION是在一個非默認名稱空間。您必須將PRIA_DOCUMENT放置在與其父級相同的名稱空間中,否則序列化程序必須生成xmlns=""

. 
    . 
<xsl:template match="PRIA_DOCUMENT"> 
    <PRIA_DOCUMENT _PRIAVersion="1.2" xmlns="http://pria.org"> 
    . 
    . 
    . 

請參閱Michael Kay的「XSLT 2.0和XPATH 2.0第4版」,第475頁,他在此討論這種確切情況。

+0

我想你的意思是'PRIA_DOCUMENT'沒有名稱空間或空名稱空間。所以命名空間fixup添加覆蓋'xmlns =「」' – 2010-08-17 16:40:10

+0

那麼我將如何處理此修復?我寧願xmlns屬性不會出現在DOCUMENT_RECORDATION子項中。這可能嗎? 命名空間是不是繼承? – alan 2010-08-17 17:30:24

+2

將xmlns =「http://pria.org」放在xsl:stylesheet元素上。這種方式適用於所有模板中的文字結果元素,除非使用xmlns =「http://aptitudesolutions.com」在模板匹配=「REQUEST_GROUP」中覆蓋它。 – 2010-08-17 17:58:13

0

您正在使用'xmlns ='聲明重新定義每個節點的默認命名空間。由於PRIA_DOCUMENT沒有名稱空間,因此輸出需要將其重新聲明爲空,否則它將具有與父級相同的名稱空間。我建議增加一個名爲命名空間給那些有一個定義的元素,例如:

<pria:DOCUMENT_RECORDATION xmlns:pria="http://pria.org">

<as:ONCORE_ERECORD xmlns:as="http://aptitudesolutions.com">

有了這些命名的命名空間,空白宣言PRIA_DOCUMENT元素變得不必要,並且不被添加。

3

將調用模板和應用模板放在同一個命名空間中。

1

我在連上聲明子元素的命名空間類似的問題,但仍然有

xmlns="" 

結束了,我認爲這是由於XSLT轉換而變換的字符串結果是正確的,當時我將字符串轉換爲org.w3c.dom.Document,以便添加默認名稱空間。

製作的DocumentBuilderFactory名稱空間感知的解決了這個問題

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
dbf.setNamespaceAware(true); 
DocumentBuilder db = dbf.newDocumentBuilder(); 
Document metadataDOM = db.parse(new ByteArrayInputStream(stringWriter.toString().getBytes())); 
+0

謝謝Dan675。在我的應用程序中,我們也遇到了這個問題,現在通過遵循你的方法來解決這個問題,使它能夠感知名稱空間。 – joy 2014-01-24 15:07:48