我是使用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
我认为我的模板匹配是“缺少”他们的目标或其他东西。我做错了什么?
答案 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">