XSLT将XML兄弟移动到子节点

时间:2013-11-13 15:44:34

标签: xml xslt

首先让我说我不知道​​我在使用XSLT做什么。我所有的XSLT都是从其他人那里继承而来的。我有一些XML(如果有帮助的话,它是EAD),它不是我们的样式表所期望的那样,因此它不会正确地转换为XHTML。

基本上,我需要<unitdate>成为<unittitle>的孩子,而不是其兄弟。

大部分文档都是这样的:

<c03 id="ref13" level="file">
<did>
<unittitle>1. President (White House)</unittitle>
<container id="cid192710" type="Box" label="Text">1</container>
<container parent="cid192710" type="Folder">2</container>
<unitdate normal="1953/1956" type="inclusive">1953-1956</unitdate>
</did>
</c03>

我需要它看起来像这样:

<c03 id="ref13" level="file">
<did>
<unittitle>1. President (White House)<unitdate normal="1953/1956" type="inclusive">1953-1956</unitdate></unittitle>
<container id="cid192710" type="Box" label="Text">1</container>
<container parent="cid192710" type="Folder">2</container>
</did>
</c03>

有一种简单的方法吗?我知道有类似的问题,但我不太了解这一点,以使其适应它以使其正常工作。感谢。

2 个答案:

答案 0 :(得分:1)

试试这些模板:

<xsl:template match="unittitle[following-sibling::unitdate]">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
    <xsl:copy-of select="following-sibling::unitdate"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="unitdate"/>

身份模板:

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

身份模板完全按原样复制所有内容。之前的两个模板会在特定情况下覆盖它,在这种情况下,您有一个unittitle元素,其后跟有unitdate个兄弟元素,以及unitdate元素本身。

您可能会注意到第一个模板与身份模板几乎完全相同 - 这是因为它以与身份模板相同的方式复制unittitle,除了它还复制了以下unitdate元素在处理完所有其他内容(即文本)之后也是如此。

单行unitdate模板只需将其从处理位置移除,而不是输出任何内容。

答案 1 :(得分:0)

要不修改现有的XSLT并且仍然能够处理incxoming XML,您可以使用以下XSLT(1.0)段来解决您的问题。

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:template match="*">
      <xsl:copy>
    <xsl:apply-templates />
      </xsl:copy>
  </xsl:template>

  <xsl:template match="did">
      <xsl:copy>
         <xsl:apply-templates select="*[local-name()!='unitdate']"/>
      </xsl:copy>
  </xsl:template>

   <xsl:template match="unittitle">
       <xsl:element name="unittitle">
             <xsl:value-of select="text()"/>
             <xsl:copy-of select="../unitdate" />
       </xsl:element>
  </xsl:template>

  <xsl:template match="@*|text()|comment()|processing-instruction">
    <xsl:copy-of select="."/>
  </xsl:template>

</xsl:stylesheet>

但你应该认真考虑不要使用它。修改现有的XSLT是合理的做法。这只会产生性能开销。