以下是一条示例消息:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://www.w3.org/2005/Atom">
<id>xxx</id>
<atom:entry xmlns:atom="http://www.w3.org/2005/Atom">
<atom:id>atom_id_01</atom:id>
<atom:content type="application/xml">
<event xmlns="http://event" xmlns:sample="unknown_namespace" id="event_id_01" type="special_type">
<sample:product a="a_01_before" b="b__01before" />
</event>
</atom:content>
</atom:entry>
<atom:entry xmlns:atom="http://www.w3.org/2005/Atom">
<atom:id>atom_id_02</atom:id>
<atom:content type="application/xml">
<event xmlns="http://event" xmlns:sample="unknown_namespace" id="event_id_02" type="special_type">
<sample:product a="a_02_before" b="b_02_before" />
</event>
</atom:content>
</atom:entry>
</root>
结果应该是:
<entries>
<entry xmlns="http://www.w3.org/2005/Atom">
<content>
<event xmlns="http://event" id="event_id_01" type="special_type">
<product a="a_01_after" b="b_01_after"/>
</event>
</content>
</entry>
<entry xmlns="http://www.w3.org/2005/Atom">
<content>
<event xmlns="http://event" id="event_id_02" type="special_type">
<product a="a_02_after" b="b_02_after"/>
</event>
</content>
</entry>
</entries>
我尝试过很多方法,发现命名空间太烦人了。我是否需要先删除命名空间?
---更新---
我用两个xslt文件应用它。
第一个将构建一个新格式的xml文件:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" method="xml" indent="no"/>
<xsl:template match="/">
<entries>
<xsl:for-each select="//*[@type='special_type']">
<xsl:copy-of select="../.."/>
</xsl:for-each>
</entries>
</xsl:template>
</xsl:stylesheet>
第二个将在某些属性上应用函数
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:utils="com.example.util">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//*/@a | //*/@b">
<xsl:variable name="aTemp" select="..//@a"></xsl:variable>
<xsl:variable name="bTemp" select="..//@b"></xsl:variable>
<xsl:attribute name="a">
<xsl:value-of select="utils:ConverterUtil.test($aTemp)"/>
</xsl:attribute>
<xsl:attribute name="b">
<xsl:value-of select="utils:ConverterUtil.test($bTemp)"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
然而,它有点奇怪的方式。我不喜欢它,因为像//*/@a
这样的表达式非常依赖于a
属性只出现一次的条件。还有更好的办法吗?
例如,product/@a
更好,因为它取决于整个xml结构。但我发现我需要在像sample:product/@a
之类的元素之前明确指定命名空间。在我的情况下,问题是命名空间一直在变化。
答案 0 :(得分:0)
以下是一个示例样式表,可帮助您入门:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:event="http://event"
xmlns:sample="sample" exclude-result-prefixes="#all"
version="2.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="atom:root">
<entries>
<xsl:apply-templates/>
</entries>
</xsl:template>
<xsl:template match="atom:root/atom:id|atom:entry/atom:id"/>
<xsl:template match="atom:entry">
<xsl:element name="entry" namespace="http://www.w3.org/2005/Atom">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="atom:content">
<xsl:element name="content" namespace="http://www.w3.org/2005/Atom">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="event:event">
<xsl:element name="event" namespace="http://event">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="*[local-name()='product']">
<xsl:element name="product" namespace="http://event">
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<!-- Do your attribute templates here. Below is just a sample -->
<xsl:template match="*[local-name()='product']/@a">
<xsl:attribute name="a_test">changed_att</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
尝试一下;比如:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:event="http://event">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/atom:root">
<entries>
<xsl:apply-templates select="@*|node()"/>
</entries>
</xsl:template>
<xsl:template match="event:event/*[local-name()='product']">
<event:product>
<xsl:attribute name="a">
<xsl:value-of select="utils:ConverterUtil.test(@a)"/>
</xsl:attribute>
<xsl:attribute name="b">
<xsl:value-of select="utils:ConverterUtil.test(@b)"/>
</xsl:attribute>
</event:product>
</xsl:template>
</xsl:stylesheet>