使用XSLT从指定文件中选择值

时间:2013-03-05 17:08:01

标签: java xml xslt

我正在使用XSLT获取一个XML文件,该文件具有特定“ID”的一堆值。我需要通过我的转换器运行它,它将这些值输出到数据库,但我必须识别的值是ID。我需要识别的值是另一个文件中的描述。这个描述应该成为输出XML的元素名称,而不是ID,这就是我现在使用的。相同的计数器ID位于单独的文件中,并包含我需要用作元素名称的描述。这是一个例子,以防我困惑你。

<!-- XML with values -->
<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
    <series>
        <sampleInfo>
            <timestamp>1/1/2013 12:00 AM</timestamp>
            <timestamp>1/2/2013 12:00 AM</timestamp>
            <timestamp>1/3/2013 12:00 AM</timestamp>
            <timestamp>1/4/2013 12:00 AM</timestamp>
        </sampleInfo>
        <value>
            <series>
                <value>
                    <int>0</int>
                    <int>9</int>
                    <int>0</int>
                    <int>9</int>
                </value>
                <id>
                    <counterID>100</counterID>
                    .
                    .
                </id>
            </series>
            <series>
                <value>
                    <int>3</int>
                    <int>6</int>
                    <int>3</int>
                    <int>6</int>
                </value>
                <id>
                    <counterID>120</counterID>
                    .
                    .
                    .
                </id>
            </series>
        </value>
    </series>
</root>

基本上,每个时间戳对每个相应的counterID都有自己的值。现在这里是另一个XML文件的示例,我正在从中获取信息。

<!-- XML with descriptions -->
<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
    <counterInfo>
        <id>100</id>
        <description>Blah</description>
    </counterInfo>
    <counterInfo>
        <id>120</id>
        <description>Derp</description>
    </counterInfo>
</root>

因此,一旦我转换原始文档(具有值的文档),我的输出(平面)XML看起来就像:

<root>
    <element>
        <timestamp>1/1/2013 12:00 AM</timestamp>
        <C100>0</C100> <!-- Since XML doesn't allow numeric element fields, I add a C -->
        <C120>3</C120>
    </element>
    <element>
        <timestamp>1/2/2013 12:00 AM</timestamp>
        <C100>9</C100>
        <C120>6</C120>
    </element>
    <element>
        <timestamp>1/3/2013 12:00 AM</timestamp>
        <C100>0</C100>
        <C120>3</C120>
    </element>
    <element>
        <timestamp>1/4/2013 12:00 AM</timestamp>
        <C100>9</C100>
        <C120>6</C120>
    </element>
</root>

我需要做的是转换已经平坦的XML,如上所述,以显示它。

<root>
    <element>
        <timestamp>1/1/2013 12:00 AM</timestamp>
        <Blah>0</Blah>
        <Derp>3</Derp>
    </element>
    <element>
        <timestamp>1/2/2013 12:00 AM</timestamp>
        <Blah>9</Blah>
        <Derp>6</Derp>
    </element>
    <element>
        <timestamp>1/3/2013 12:00 AM</timestamp>
        <Blah>0</Blah>
        <Derp>3</Derp>
    </element>
    <element>
        <timestamp>1/4/2013 12:00 AM</timestamp>
        <Blah>9</Blah>
        <Derp>6</Derp>
    </element>
</root>

我做了一些搜索,大多数结果都提示参数,但我转换它们的方式可能会让这有点困难。我有一个Java转换器,它是大型转换器存储库的一部分,它从该存储库中提取XSLT来转换传递给它的文件。在转换器中,我们提取需要从归档转换的文件,然后分别对每个文件进行转换。所以我的问题是......当转换器到达列表中的那个文件时,如何给XSLT提供文件名,以及如何将该文件名传递给XSLT?

所以我过于复杂了吗?有没有简单的方法来实现这一目标?如果我需要清除任何内容,请告诉我。

1 个答案:

答案 0 :(得分:1)

打开文档非常简单,可以参数化。但是创建一个'C'的元素名称concat某个数字(例如,'C100')是一个可怕的,可怕的,可怕的想法。为什么?因为找到那些节点非常困难(在xsl中);此外,'C100''C125'节点会打消任何创建架构的尝试。

使用属性<descr id="100">0</descr>

,而不是创建自己的元素

输入XML(file.xml)

好的,所以,这是一个使用descr元素的xml:

<root>
    <element>
        <timestamp>1/1/2013 12:00 AM</timestamp>
        <descr id="100">0</descr>
        <descr id="120">3</descr>
    </element>
    <element>
        <timestamp>1/2/2013 12:00 AM</timestamp>
        <descr id="100">9</descr>
        <descr id="120">6</descr>
    </element>
    <element>
        <timestamp>1/3/2013 12:00 AM</timestamp>
        <descr id="100">0</descr>
        <descr id="120">3</descr>
    </element>
    <element>
        <timestamp>1/4/2013 12:00 AM</timestamp>
        <descr id="100">9</descr>
        <descr id="120">6</descr>
    </element>
</root>

描述XML(descript.xml)

<root>
    <counterInfo>
        <id>100</id>
        <description>Blah</description>
    </counterInfo>
    <counterInfo>
        <id>120</id>
        <description>Derp</description>
    </counterInfo>
</root>

XSL

最后,合并它们的样式表:

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

    <xsl:param name="descrDoc" select="'descriptions.xml'" />

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

    <xsl:template match="descr">
      <xsl:variable name="nodeName">
        <xsl:value-of select="document($descrDoc)/*/counterInfo[ id = current()/@id ]/description" />
      </xsl:variable>
      <xsl:if test="string-length($nodeName)=0">
        <xsl:message terminate="yes">No description! Failed.</xsl:message>
      </xsl:if>
      <xsl:element name="{$nodeName}">
        <xsl:apply-templates />
      </xsl:element>
    </xsl:template>

</xsl:stylesheet>