基于规则的节点重组

时间:2014-03-26 13:50:57

标签: xslt

假设我有以下XML文件,其中包含我想根据规则重新排列的节点:

<root>   
  <subsection key="KeyR">Some text</subsection>
  <subsection key="KeyC">Some text</subsection>
  <subsection key="KeyE">Some text</subsection>
  <subsection key="KeyG">Some text</subsection>
  <subsection key="KeyH">Some text</subsection>
  <subsection key="KeyI">Some text</subsection>
  <subsection key="KeyF">Some text</subsection>
  <subsection key="KeyJ">Some text</subsection>
  <subsection key="KeyL">Some text</subsection>
  <subsection key="KeyA"/>
  <subsection key="KeyM">Some text</subsection>
  <subsection key="KeyN">Some text</subsection>
  <subsection key="KeyO">Some text</subsection>
  <subsection key="KeyS">Some text</subsection>
  <subsection key="KeyP">Some text</subsection>
  <subsection key="KeyQ">Some text</subsection>
  <subsection key="KeyD">Some text</subsection>
  <subsection key="KeyB"/>
  <subsection key="KeyT">Some text</subsection>
  <subsection key="KeyK">Some text</subsection> 
  <subsection key="KeyZ">Some text</subsection>  
</root>

和重新排列的规则如下:

section01
  KeyA
  KeyM
  KeyZ
section02
  KeyL
  KeyN
  KeyP
section03
  ..
  ..
section04
 ..

这些规则将子节的键分配给新的parend节。这样会产生以下XML文件:

<root>
  <section1>
    <subsection key="KeyA"/>
    <subsection key="KeyM">Some text</subsection>
    <subsection key="KeyZ">Some text</subsection>
  </section1>
  <section2>
    <subsection key="KeyL">Some text</subsection>
    <subsection key="KeyN">Some text</subsection>
    <subsection key="KeyP">Some text</subsection>
  </section2>
  <section3>
    ...
  </section3>
  ...
</root>

将是XSL转换的适当手段吗?这样的转变怎么样?什么是规则的适当表现,以便可以轻松维护规则?

1 个答案:

答案 0 :(得分:1)

如果您可以在与XSLT样式表文件相同的目录中存在rules.xml文件(例如),则采用以下格式:

<强> rules.xml中

<?xml version="1.0" encoding="UTF-8"?>
<rules>
    <section id="01">
        <key>KeyA</key>
        <key>KeyM</key>
        <key>KeyZ</key>
    </section>
    <section id="02">
        <key>KeyL</key>
        <key>KeyN</key>
        <key>KeyP</key>
    </section>
</rules>

然后,您可以将以下样式表应用于您的输入:

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:key name="sub" match="subsection" use="@key" />
<xsl:variable name="root" select="/" />

<xsl:template match="/">
<root>
    <xsl:for-each select="document('rules.xml')/rules/section">
    <xsl:variable name="keys" select="key" />
    <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:for-each select="$root">
            <xsl:copy-of select="key('sub', $keys)"/>
        </xsl:for-each> 
    </xsl:copy>
    </xsl:for-each> 
</root>
</xsl:template>

</xsl:stylesheet>

获得以下结果:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <section id="01">
      <subsection key="KeyA"/>
      <subsection key="KeyM">Some text</subsection>
      <subsection key="KeyZ">Some text</subsection>
   </section>
   <section id="02">
      <subsection key="KeyL">Some text</subsection>
      <subsection key="KeyN">Some text</subsection>
      <subsection key="KeyP">Some text</subsection>
   </section>
</root>

编辑:

要取消输入文档中没有匹配子节的节规则,请尝试:

<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:key name="sub" match="subsection" use="@key" />
<xsl:variable name="root" select="/" />

<xsl:template match="/">
<root>
    <xsl:for-each select="document('file2.xml')/rules/section">
        <xsl:variable name="id" select="@id" />
        <xsl:variable name="keys" select="key" />
        <xsl:for-each select="$root">
            <xsl:if test="key('sub', $keys)">
                <section id="{$id}">
                    <xsl:copy-of select="key('sub', $keys)"/>
                </section>
                </xsl:if>
        </xsl:for-each> 
    </xsl:for-each> 
</root>
</xsl:template>

</xsl:stylesheet>