2010-08-17 71 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