基本XSLT的麻烦

时间:2013-10-08 12:05:56

标签: xml xslt

我是使用XSLT的新手,我正在尝试将基本XML文件转换为SQL以插入数据库。

我正在尝试改造:

<?xml version="1.0" standalone="yes"?>
<DataStore xmlns="Microsystems.D3.DataEngine">
  <DDA_Atoms>
    <ID>22d2e980-f13b-43be-83a8-4b72cd38c053</ID>
    <CONTENT />
    <NAME>name 1</NAME>
    <PREVIEW>preview 1</PREVIEW>
    <STRUCTURE_ELEMENT_ID>1</STRUCTURE_ELEMENT_ID>
    <HASH>-2013036173</HASH>
    <PATH>C:\dir1</PATH>
    <SIZE>88331</SIZE>
  </DDA_Atoms>
  <DDA_Atoms>
    <ID>4a1b0532-db0c-4790-9e71-92f6d84b4ad2</ID>
    <CONTENT />
    <NAME>Name 2</NAME>
    <PREVIEW>preview 2</PREVIEW>
    <STRUCTURE_ELEMENT_ID>2</STRUCTURE_ELEMENT_ID>
    <HASH>-1467957647</HASH>
    <PATH>C:\dir2</PATH>
    <SIZE>220557</SIZE>
  </DDA_Atoms>
</DataStore>

使用以下XSL:

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" encoding="iso-8859-1"/>
<xsl:template match="DataStore">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="DDA_Atoms">
    <xsl:text>INSERT INTO DDA_Atoms VALUES ('</xsl:text >
        <xsl:value-of select="ID"/>
        <xsl:text>', '</xsl:text>
        <xsl:value-of select="CONTENT"/>
        <xsl:text>', '</xsl:text>
        <xsl:value-of select="NAME"/>
        <xsl:text>', '</xsl:text>
        <xsl:value-of select="PREVIEW"/>
        <xsl:text>', </xsl:text>
        <xsl:value-of select="STRUCTURE_ELEMENT_ID"/>
        <xsl:text>, </xsl:text>
        <xsl:value-of select="HASH"/>
        <xsl:text>, '</xsl:text>
        <xsl:value-of select="PATH"/>
        <xsl:text>', </xsl:text>
        <xsl:value-of select="SIZE"/>
        <xsl:text>)</xsl:text>
    <xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>

但是当我在XML上运行XSL时,它只返回节点的值而不是文字的SQL文本。更重要的是,它实际上忽略了所有的XSL,因为当我删除所有模板匹配代码并基本上留下一个空的XSL文档时,转换完全相同:只返回节点的所有值,如:

22d2e980-f13b-43be-83a8-4b72cd38c053name 1preview 11-2013036173C:\dir1883314a1b0532-db0c-4790-9e71-92f6d84b4ad2Name 2preview 22-1467957647C:\dir2220557

我认为我的模板匹配是“缺少”他们的目标或其他东西。我做错了什么?

1 个答案:

答案 0 :(得分:2)

问题是因为XML中的名称空间声明

<DataStore xmlns="Microsystems.D3.DataEngine">

这意味着此元素及其所有后代都属于此命名空间。但是,在XSLT中没有对名称空间的引用,因此所有xpath表达式都在查找没有名称空间的元素,并且与XML不匹配。您只是因为将使用XSLT的内置模板而获得文本输出,并且这些模板将在他们找到的地方输出文本节点。

您需要做的是首先在XSLT中使用名称空间前缀

声明名称空间
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
                xmlns:da="Microsystems.D3.DataEngine">

然后,无论您何时引用元素,都需要在其前面加上命名空间前缀。例如:

<xsl:template match="da:DataStore">

试试这个XSLT

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:da="Microsystems.D3.DataEngine">
<xsl:output method="text" encoding="iso-8859-1"/>
<xsl:template match="da:DataStore">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="da:DDA_Atoms">
    <xsl:text>INSERT INTO DDA_Atoms VALUES ('</xsl:text >
        <xsl:value-of select="da:ID"/>
        <xsl:text>', '</xsl:text>
        <xsl:value-of select="da:CONTENT"/>
        <xsl:text>', '</xsl:text>
        <xsl:value-of select="da:NAME"/>
        <xsl:text>', '</xsl:text>
        <xsl:value-of select="da:PREVIEW"/>
        <xsl:text>', </xsl:text>
        <xsl:value-of select="da:STRUCTURE_ELEMENT_ID"/>
        <xsl:text>, </xsl:text>
        <xsl:value-of select="da:HASH"/>
        <xsl:text>, '</xsl:text>
        <xsl:value-of select="da:PATH"/>
        <xsl:text>', </xsl:text>
        <xsl:value-of select="da:SIZE"/>
        <xsl:text>)</xsl:text>
</xsl:template>
</xsl:stylesheet>

另请注意,第二个模板中不需要<xsl:apply-templates/>,因为您已经处理了所有孩子。

注意:如果您使用的是XSLT 2.0,则可以使用“xpath-default-namespace”选项来声明默认命名空间。然后你就不必更改任何模板来使用命名空间前缀,因为XSLT会假设没有前缀的任何模板都在这个默认命名空间中(而不是没有命名空间)。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
                xpath-default-namespace="Microsystems.D3.DataEngine">