2

我有以下 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>

我不知道发生了什么以及如何解决这个问题。有什么建议么?万分感谢

4

1 回答 1

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 文档上产生错误的结果。可以提供正确且更通用的转换,但我相信这就是您所要求的。

于 2013-03-27T03:51:41.013 回答