XSLT变量计数器和相关节点

时间:2015-10-24 20:21:03

标签: xml xslt

我没有写过xsl转换的知识。我有一个像这样的xml

<details>
    <order>
        <id>testID</id>
        <name>testName</name>
    </order>
    <contract>
        <id>1234</id>
        <date>01-01-2015</date>
        <contactAddress>
            <name>ABC</name>
            <email>abc@asd.com</email>
        </contactAddress>
    </contract>
</details>

我想转换这个xml,其中每个具有子节点的节点将形成一个项目,并且还将使用itemID和relatedItemID维护关系

喜欢这个

<items>
    <item>
        <name>order</name>
        <itemID>1</itemID>
        <characteristics>
            <characterisctic>
                <name>id</name>
                <value>testID</value>
            </characterisctic>
            <characterisctic>
                <name>name</name>
                <value>testName</value>
            </characterisctic>
        </characteristics>
    </item>
    <item>
        <name>contract</name>
        <itemID>2</itemID>
        <characteristics>
            <characterisctic>
                <name>id</name>
                <value>1234</value>
            </characterisctic>
            <characterisctic>
                <name>date</name>
                <value>01-01-2015</value>
            </characterisctic>
        </characteristics>
    </item>
    <item>
        <name>contactAddress</name>
        <itemID>3</itemID>
        <relatedItemID>2</relatedItemID>
        <characteristics>
            <characterisctic>
                <name>name</name>
                <value>ABC</value>
            </characterisctic>
            <characterisctic>
                <name>email</name>
                <value>abc@asd.com</value>
            </characterisctic>
        </characteristics>
    </item>
</items>

为此,我写了一个像这样的xsl。

<xsl:stylesheet 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  version="1.0"
  >
    <xsl:variable name="i"></xsl:variable>
    <xsl:template match="/">
        <items>
            <xsl:apply-templates select="//order"/>
            <xsl:apply-templates select="//contract"/>
        </items>
    </xsl:template>
    <xsl:template match="*">
        <item>
            <name><xsl:value-of select="local-name()"/></name>
            <itemID><xsl:value-of select="position()" /></itemID>
            <characteristics>
                <xsl:for-each select="./*">
                    <xsl:choose>
                        <xsl:when test="*">
                            <xsl:apply-templates select="."></xsl:apply-templates>
                        </xsl:when>
                        <xsl:otherwise>
                            <characterisctic>
                                <name> <xsl:value-of select="local-name()"/></name>
                                <value><xsl:value-of select="."/></value>
                            </characterisctic>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:for-each>
            </characteristics>
        </item>
    </xsl:template>
</xsl:stylesheet>

但我无法弄清楚如何为每个项目保留单独的itemID并使用relatedItemID维护关系

如何编写xsl来实现此目的?

1 个答案:

答案 0 :(得分:1)

也许像这样的通用解决方案可能适合您:

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="/">
    <items>
        <xsl:apply-templates/>
    </items>
</xsl:template>

<xsl:template match="*[*]">
    <item>
        <name>
            <xsl:value-of select="name()"/>
        </name>
        <itemID>
            <xsl:value-of select="generate-id()" />
        </itemID>
        <parentItemID>
            <xsl:value-of select="generate-id(..)" />
        </parentItemID>
        <xsl:variable name="chars" select="*[not(*)]" />
        <xsl:if test="$chars">
            <characteristics>
                <xsl:apply-templates select="$chars" />
            </characteristics>
        </xsl:if>
    </item>
    <xsl:apply-templates select="*[*]" />
</xsl:template>

<xsl:template match="*">
    <characteristic>
        <name>
            <xsl:value-of select="name()"/>
        </name>
        <value>
            <xsl:value-of select="." />
        </value>
    </characteristic>
</xsl:template>

</xsl:stylesheet>

应用于您的示例输入,结果将类似(id值取决于处理器):

<?xml version="1.0" encoding="UTF-8"?>
<items>
   <item>
      <name>details</name>
      <itemID>d0e1</itemID>
      <parentItemID>d0</parentItemID>
   </item>
   <item>
      <name>order</name>
      <itemID>d0e2</itemID>
      <parentItemID>d0e1</parentItemID>
      <characteristics>
         <characteristic>
            <name>id</name>
            <value>testID</value>
         </characteristic>
         <characteristic>
            <name>name</name>
            <value>testName</value>
         </characteristic>
      </characteristics>
   </item>
   <item>
      <name>contract</name>
      <itemID>d0e7</itemID>
      <parentItemID>d0e1</parentItemID>
      <characteristics>
         <characteristic>
            <name>id</name>
            <value>1234</value>
         </characteristic>
         <characteristic>
            <name>date</name>
            <value>01-01-2015</value>
         </characteristic>
      </characteristics>
   </item>
   <item>
      <name>contactAddress</name>
      <itemID>d0e12</itemID>
      <parentItemID>d0e7</parentItemID>
      <characteristics>
         <characteristic>
            <name>name</name>
            <value>ABC</value>
         </characteristic>
         <characteristic>
            <name>email</name>
            <value>abc@asd.com</value>
         </characteristic>
      </characteristics>
   </item>
</items>