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

copy the entire block under another node - xslt transformation

我是 XSL 编码的新手,在这里我试图获取整个 (result) 节点块并放置在另一个名为 RESULTS[=27 的节点中=]...下面是我的 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>

您可以像这样移动添加的 results 块中的所有 result 块:

<?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"> 只是复制了新 results 块内的所有后续 result 节点。

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

Could anyone help me where am i doing it wrongly?

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

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

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

除此之外,如果您希望将结果放置在“另一个名为 RESULTS 的节点内”,则不要放置他们在 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>