将整个块复制到另一个节点下 - xslt转换

时间:2015-01-04 03:56:32

标签: xml xslt xslt-2.0

我是XSL编码的新手,在这里我试图占用(结果)节点的整个块并放置在另一个名为 RESULTS 的节点...下面是我的使用xml和xsl。

但它没有像预期的那样改变xml ......

任何人都可以帮助我,我在哪里做错了吗?

XML

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="samplexslt.xsl"?> 
<report>
<Header>
 <RegNo>123</RegNo>
 <EmrNo>op2145</EmrNo>
 <BillNo>opcb1234-12</BillNo>
 <Uhid>1209</Uhid>
 <AdmissionDate>13-Jan-2014</AdmissionDate>
</Header>

<result>
 <name>test1</name>
 <desc1>abcdefghijklmnopqrstuvwxyz</desc1>
 <desc2>description</desc2>
</result>
<result>
 <name>test2</name>
 <desc1>abcdefghijklmnopqrstuvwxyz</desc1>
</result>

<Footer>
<DoctorSign>Anand</DoctorSign>
</Footer>
</report>

XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/report">
<xsl:copy>
<xsl:apply-templates select="@*|node()[local-name() != 'result']"/>
</xsl:copy>
<notes>
<xsl:apply-templates select="result" />
</notes>
</xsl:template>

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

预期

 <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="samplexslt.xsl"?> 
<report>
<Header>
 <RegNo>123</RegNo>
 <EmrNo>op2145</EmrNo>
 <BillNo>opcb1234-12</BillNo>
 <Uhid>1209</Uhid>
 <AdmissionDate>13-Jan-2014</AdmissionDate>
</Header>

<results>    
 <result>
  <name>test1</name>
  <desc1>abcdefghijklmnopqrstuvwxyz</desc1>
  <desc2>description</desc2>
 </result>
 <result>
  <name>test2</name>
  <desc1>abcdefghijklmnopqrstuvwxyz</desc1>
 </result>
</results>

<Footer>
<DoctorSign>Anand</DoctorSign>
</Footer>
</report>

2 个答案:

答案 0 :(得分:2)

您可以移动添加的result块中的所有results块,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
 <xsl:strip-space elements="*"/>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="result">
    <results>
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
      <xsl:apply-templates select="following::result" mode="copy"/>
    </results>
  </xsl:template>
  <xsl:template match="result[preceding-sibling::result]"/>
  <xsl:template match="result" mode="copy">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

输出,当应用于输入XML时:

<report>
 <Header>
    <RegNo>123</RegNo>
    <EmrNo>op2145</EmrNo>
    <BillNo>opcb1234-12</BillNo>
    <Uhid>1209</Uhid>
    <AdmissionDate>13-Jan-2014</AdmissionDate>
  </Header>
  <results>
    <result>
     <name>test1</name>
     <desc1>abcdefghijklmnopqrstuvwxyz</desc1>
     <desc2>description</desc2>
    </result>
    <result>
     <name>test2</name>
     <desc1>abcdefghijklmnopqrstuvwxyz</desc1>
    </result>
  </results>
  <Footer>
    <DoctorSign>Anand</DoctorSign>
  </Footer>
</report>

空模板<xsl:template match="result[preceding-sibling::result]"/>匹配具有前面结果节点的所有结果节点,因此<xsl:template match="result">仅匹配第一个结果。
在此模板中,使用

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

复制第一个结果,然后将mode="copy"的模板应用于以下所有结果:

  <xsl:apply-templates select="following::result" mode="copy"/>

<xsl:template match="result" mode="copy">只复制新result块中的所有后续results个节点。

请注意,这种方法虽然有效,但可能会过于复杂。如果你的输入XML只包含已知的标题,结果和页脚,我建议只使用michael.hor257k给出的详细答案中提供的XSLT。

答案 1 :(得分:0)

  

任何人都可以帮助我,我在哪里做错了吗?

您的方法的主要问题(有几个)是您已经放置了指令:

<notes>
    <xsl:apply-templates select="result" />
</notes>

<xsl:copy>块之外 - 因此完全在report元素之外。你应该将它放在里面,并且 - 如果你想让结果出现在页眉和页脚之间 - 你必须分别对它们应用模板。

除此之外,如果您希望将结果“放在名为结果 的另一个节点内”,则不要将它们放在notes内。

另请注意,XML区分大小写:RESULTS与预期输出中显示的results不同。

以这种方式尝试:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="/report">
    <xsl:copy>
        <xsl:apply-templates select="Header"/>
        <results>
            <xsl:apply-templates select="result" />
        </results>
        <xsl:apply-templates select="Footer" />
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

当然,如果您的样式表确实是所有,那么您可以将其缩小为:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/report">
    <xsl:copy>
        <xsl:copy-of select="Header"/>
        <results>
            <xsl:copy-of select="result" />
        </results>
        <xsl:copy-of select="Footer" />
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>