我有以下XML
<response>
<Contacts>
<Contact>
<Name>John Doe</Name>
<Age>48</Age>
<DOB>
<Day>12</Day>
<Month>6</Month>
<Year>1964</Year>
</DOB>
<Contacts>
<Contact>
<Name>Jane Walsh</Name>
<Age>30</Age>
<DOB>
<Day>24</Day>
<Month>3</Month>
<Year>1983</Year>
</DOB>
</Contact>
<Contact>
<Name>Rob Marsh</Name>
<Age>55</Age>
<DOB>
<Day>1</Day>
<Month>Feb</Month>
<Year>1958</Year>
</DOB>
</Contact>
</Contacts>
</Contact>
</Contacts>
</response>
我使用身份转换将结构复制到目标。
<xsl:template name = "testTemplate" match="/*[local-name()='response']/*">
<xsl:apply-templates mode="copy-no-ns" select="response"/>
</xsl:template>
<!-- Selectively mass copy some of the nodes without namespaces -->
<xsl:template mode="copy-no-ns" match="*">
<xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates mode="copy-no-ns" select="node()"/>
</xsl:element>
</xsl:template>
XSL在Altova XMLSpy中工作,当我使用Visual Studio 2010测试它时产生所需的输出。但是BizTalk映射会产生如下的空节点(删除正确复制的其他内容)。
<Contacts>
<Contact>
<Contacts>
<Contact />
<Contact />
</Contacts>
<Contact>
</Contacts>
我不知道发生了什么以及如何解决这个问题。有什么建议?万分感谢
答案 0 :(得分:4)
你明显的问题在于:
<xsl:template name = "testTemplate" match="/*[local-name()='response']/*"> <xsl:apply-templates mode="copy-no-ns" select="response"/> </xsl:template>
此模板匹配顶部元素response
的任何子元素(在本例中只是名为Contacts
的元素。
然后,它将模板应用于匹配的Contacts
元素的所有子项,名为response
。 但是,Contacts
元素没有名为response
的子元素。此时,转换不能再产生任何输出。
最终结果只是:
<response>
</response>
以下是完整转型:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template name = "testTemplate" match="/*[local-name()='response']/*">
<xsl:apply-templates mode="copy-no-ns" select="response"/>
</xsl:template>
<!-- Selectively mass copy some of the nodes without namespaces -->
<xsl:template mode="copy-no-ns" match="*">
<xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates mode="copy-no-ns" select="node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档时:
<response>
<Contacts>
<Contact>
<Name>John Doe</Name>
<Age>48</Age>
<DOB>
<Day>12</Day>
<Month>6</Month>
<Year>1964</Year>
</DOB>
<Contacts>
<Contact>
<Name>Jane Walsh</Name>
<Age>30</Age>
<DOB>
<Day>24</Day>
<Month>3</Month>
<Year>1983</Year>
</DOB>
</Contact>
<Contact>
<Name>Rob Marsh</Name>
<Age>55</Age>
<DOB>
<Day>1</Day>
<Month>Feb</Month>
<Year>1958</Year>
</DOB>
</Contact>
</Contacts>
</Contact>
</Contacts>
</response>
结果如上所述:
<response>
</response>
<强>解决方案强>:
只需替换:
<xsl:apply-templates mode="copy-no-ns" select="response"/>
<强>与强>:
<xsl:apply-templates mode="copy-no-ns" select="node()"/>
完整转化:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template name = "testTemplate" match="/*[local-name()='response']/*">
<xsl:apply-templates mode="copy-no-ns" select="node()"/>
</xsl:template>
<!-- Selectively mass copy some of the nodes without namespaces -->
<xsl:template mode="copy-no-ns" match="*">
<xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates mode="copy-no-ns" select="node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
在提供的XML文档(上面)上应用此转换时,生成所需结果:
<response>
<Contact>
<Name>John Doe</Name>
<Age>48</Age>
<DOB>
<Day>12</Day>
<Month>6</Month>
<Year>1964</Year>
</DOB>
<Contacts>
<Contact>
<Name>Jane Walsh</Name>
<Age>30</Age>
<DOB>
<Day>24</Day>
<Month>3</Month>
<Year>1983</Year>
</DOB>
</Contact>
<Contact>
<Name>Rob Marsh</Name>
<Age>55</Age>
<DOB>
<Day>1</Day>
<Month>Feb</Month>
<Year>1958</Year>
</DOB>
</Contact>
</Contacts>
</Contact>
</response>
请注意:
此转换假定元素没有属性。如果此假设不成立,则转换会在具有属性的任何XML文档上产生错误的结果。可以提供正确且更通用的转换,但我相信这就是您所要求的。