XSLT:将子节点移动到XML中的父节点的通用方法

时间:2016-09-29 22:50:25

标签: xml xslt xslt-1.0

我有以下xml结构:

<root>
  <p1>
    <a>1</a>
    <b>2</b>
    <_timestamp>20160928201109</_timestamp>
    <c>
    <_c_timestamp>20160928201056</_c_timestamp>Tmp</c>
  </p1>
  <p2>
    <a>1</a>
    <b>2</b>
    <_timestamp>20160928201109</_timestamp>
    <d>
    <_d_timestamp>20160928201056</_d_timestamp>Tmp1</d>
  </p2>
</root>

并希望使用XSLT转换为此结构:

<root>
  <p1>
    <a>1</a>
    <b>2</b>
    <_timestamp>20160928201109</_timestamp>
    <_c_timestamp>20160928201056</_c_timestamp>
    <c>Tmp</c>
  </p1>
  <p2>
    <a>1</a>
    <b>2</b>
    <_timestamp>20160928201109</_timestamp>
    <_d_timestamp>20160928201056</_d_timestamp>
    <d>Tmp1</d>
  </p2>
</root>

即,任何具有结构<_anyName_timestamp>的标记都应该移动到父节点。

任何指向XSLT结构的指针都会有所帮助。

1 个答案:

答案 0 :(得分:1)

  

任何带有结构<_anyName_timestamp>的标记都应该出现   移到父节点。

移动是这里的一个简单部分。困难的部分是确定要移动的元素。尝试:

XSLT 1.0

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

<xsl:template match="*">
    <xsl:apply-templates select="*[starts-with(name(), '_') and contains(substring(name(), 2), '_timestamp')]"/>
    <xsl:copy>
        <xsl:apply-templates select="node()[not(starts-with(name(), '_') and contains(substring(name(), 2), '_timestamp'))]"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

或者更优雅一点:

<xsl:template match="*">
    <xsl:variable name="ts" select="*[starts-with(name(), '_') and contains(substring(name(), 2), '_timestamp')]" />
    <xsl:apply-templates select="$ts"/>
    <xsl:copy>
        <xsl:apply-templates select="node()[count(.|$ts) > count($ts)]"/>
    </xsl:copy>
</xsl:template>