XSLT 复制没有 default/old 命名空间的元素
XSLT to copy element without default/old namespace
我正在使用 XSLT 从一个 XML 文档转换为另一个 XML 文档。输入和输出文档类型都在不同的默认名称 space 中。我曾经先进行转换,然后根据输出模式使用 JAXB 进行过滤。
我的要求是:如果 publisher/catalogue/cd11/year 在输入 xml 中是 available/exist 那么需要在输出 publisher/catalogue/cd22 = 'New Release' 中创建一个具有值的新元素 xml。 (仅供参考。publisher/catalogue/cd22 存在于输出模式中)
问题:当我使用下面提到的 XSLT 进行转换时,正在创建输出名称为 space 的新节点,但父节点添加了输入 xml 名称space / path-default-namespace (http://www.altova.com) ,我不确定为什么要添加这个但是,我确定 JAXB 正在将其过滤到所需的输出
有人可以帮忙吗?
输入XML:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://www.altova.com">
<publisher>
<Name id="d123">
<Location>Chicago</Location>
</Name>
<catalogue id="d1" >
<cd11 id="d2">
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<year>1985</year>
</cd11>
</catalogue>
<catalogue id="d3" >
<cd11 id="d4">
<title>Jurassic World</title>
<artist>Chris Pratt</artist>
</cd11>
</catalogue>
</publisher>
</root>
XSLT :
<xsl:stylesheet version="2.0" xpath-default-namespace="http://www.altova.com" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:functx="http://www.functx.com" >
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="catalogue[string(cd11/year)]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:element name="cd22" >
<xsl:value-of select="'New Release'" />
</xsl:element>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
变形后
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root xmlns="http://example.com/">
<publisher>
<Name id="d123">
<Location>Chicago</Location>
</Name>
<catalogue xmlns="http://www.altova.com" id="d1" >
<cd11 xmlns="http://example.com/" id="d2">
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<year>1985</year>
</cd11>
<cd22 xmlns="http://example.com/">New Release</cd22>
</catalogue>
<catalogue id="d3" >
<cd11 id="d4">
<title>Jurassic World</title>
<artist>Chris Pratt</artist>
</cd11>
</catalogue>
</publisher>
</root>
错误的输出:在使用 JAXB 过滤后针对具有名称 space 的输出模式作为 xmlns="http://example.com/">
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root xmlns="http://example.com/">
<publisher>
<Name id="d123">
<Location>Chicago</Location>
</Name>
<catalogue id="d3" >
<cd11 id="d4">
<title>Jurassic World</title>
<artist>Chris Pratt</artist>
</cd11>
</catalogue>
</publisher>
</root>
期望输出XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root xmlns="http://example.com/">
<publisher>
<Name id="d123">
<Location>Chicago</Location>
</Name>
<catalogue id="d1" >
<cd11 id="d2">
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<year>1985</year>
</cd11>
<cd22>New Release</cd22>
</catalogue>
<catalogue id="d3" >
<cd11 id="d4">
<title>Jurassic World</title>
<artist>Chris Pratt</artist>
</cd11>
</catalogue>
</publisher>
</root>
就这么简单:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output standalone="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pNewNS" select="'http://example.com/'"/>
<xsl:variable name="vOldNS" select="namespace-uri(/*)"/>
<xsl:template match="@*"><xsl:copy/></xsl:template>
<xsl:template match="*[namespace-uri() eq $vOldNS]">
<xsl:element name="{name()}" namespace="{$pNewNS}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template priority="3" match="*[@id eq 'd1']/*[*[name() = 'year']]">
<xsl:next-match/>
<xsl:element name="cd22" namespace="{$pNewNS}">New Release</xsl:element>
</xsl:template>
</xsl:stylesheet>
当此转换应用于提供的 XML 文档时:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://www.altova.com">
<publisher>
<Name id="d123">
<Location>Chicago</Location>
</Name>
<catalogue id="d1" >
<cd11 id="d2">
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<year>1985</year>
</cd11>
</catalogue>
<catalogue id="d3" >
<cd11 id="d4">
<title>Jurassic World</title>
<artist>Chris Pratt</artist>
</cd11>
</catalogue>
</publisher>
</root>
产生了想要的、正确的结果:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root xmlns="http://example.com/">
<publisher>
<Name id="d123">
<Location>Chicago</Location>
</Name>
<catalogue id="d1">
<cd11 id="d2">
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<year>1985</year>
</cd11>
<cd22>New Release</cd22>
</catalogue>
<catalogue id="d3">
<cd11 id="d4">
<title>Jurassic World</title>
<artist>Chris Pratt</artist>
</cd11>
</catalogue>
</publisher>
</root>
解释:
阅读并了解 <xsl:element> 指令。
阅读并了解 namespace-uri() 函数。
阅读并了解 <xsl:next-match> 指令。很少有人知道这条指令,也不知道它有多么强大和有用。
我正在使用 XSLT 从一个 XML 文档转换为另一个 XML 文档。输入和输出文档类型都在不同的默认名称 space 中。我曾经先进行转换,然后根据输出模式使用 JAXB 进行过滤。 我的要求是:如果 publisher/catalogue/cd11/year 在输入 xml 中是 available/exist 那么需要在输出 publisher/catalogue/cd22 = 'New Release' 中创建一个具有值的新元素 xml。 (仅供参考。publisher/catalogue/cd22 存在于输出模式中)
问题:当我使用下面提到的 XSLT 进行转换时,正在创建输出名称为 space 的新节点,但父节点添加了输入 xml 名称space / path-default-namespace (http://www.altova.com) ,我不确定为什么要添加这个但是,我确定 JAXB 正在将其过滤到所需的输出
有人可以帮忙吗?
输入XML:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://www.altova.com">
<publisher>
<Name id="d123">
<Location>Chicago</Location>
</Name>
<catalogue id="d1" >
<cd11 id="d2">
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<year>1985</year>
</cd11>
</catalogue>
<catalogue id="d3" >
<cd11 id="d4">
<title>Jurassic World</title>
<artist>Chris Pratt</artist>
</cd11>
</catalogue>
</publisher>
</root>
XSLT :
<xsl:stylesheet version="2.0" xpath-default-namespace="http://www.altova.com" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:functx="http://www.functx.com" >
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="catalogue[string(cd11/year)]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:element name="cd22" >
<xsl:value-of select="'New Release'" />
</xsl:element>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
变形后
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root xmlns="http://example.com/">
<publisher>
<Name id="d123">
<Location>Chicago</Location>
</Name>
<catalogue xmlns="http://www.altova.com" id="d1" >
<cd11 xmlns="http://example.com/" id="d2">
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<year>1985</year>
</cd11>
<cd22 xmlns="http://example.com/">New Release</cd22>
</catalogue>
<catalogue id="d3" >
<cd11 id="d4">
<title>Jurassic World</title>
<artist>Chris Pratt</artist>
</cd11>
</catalogue>
</publisher>
</root>
错误的输出:在使用 JAXB 过滤后针对具有名称 space 的输出模式作为 xmlns="http://example.com/">
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root xmlns="http://example.com/">
<publisher>
<Name id="d123">
<Location>Chicago</Location>
</Name>
<catalogue id="d3" >
<cd11 id="d4">
<title>Jurassic World</title>
<artist>Chris Pratt</artist>
</cd11>
</catalogue>
</publisher>
</root>
期望输出XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root xmlns="http://example.com/">
<publisher>
<Name id="d123">
<Location>Chicago</Location>
</Name>
<catalogue id="d1" >
<cd11 id="d2">
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<year>1985</year>
</cd11>
<cd22>New Release</cd22>
</catalogue>
<catalogue id="d3" >
<cd11 id="d4">
<title>Jurassic World</title>
<artist>Chris Pratt</artist>
</cd11>
</catalogue>
</publisher>
</root>
就这么简单:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output standalone="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pNewNS" select="'http://example.com/'"/>
<xsl:variable name="vOldNS" select="namespace-uri(/*)"/>
<xsl:template match="@*"><xsl:copy/></xsl:template>
<xsl:template match="*[namespace-uri() eq $vOldNS]">
<xsl:element name="{name()}" namespace="{$pNewNS}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template priority="3" match="*[@id eq 'd1']/*[*[name() = 'year']]">
<xsl:next-match/>
<xsl:element name="cd22" namespace="{$pNewNS}">New Release</xsl:element>
</xsl:template>
</xsl:stylesheet>
当此转换应用于提供的 XML 文档时:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://www.altova.com">
<publisher>
<Name id="d123">
<Location>Chicago</Location>
</Name>
<catalogue id="d1" >
<cd11 id="d2">
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<year>1985</year>
</cd11>
</catalogue>
<catalogue id="d3" >
<cd11 id="d4">
<title>Jurassic World</title>
<artist>Chris Pratt</artist>
</cd11>
</catalogue>
</publisher>
</root>
产生了想要的、正确的结果:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root xmlns="http://example.com/">
<publisher>
<Name id="d123">
<Location>Chicago</Location>
</Name>
<catalogue id="d1">
<cd11 id="d2">
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<year>1985</year>
</cd11>
<cd22>New Release</cd22>
</catalogue>
<catalogue id="d3">
<cd11 id="d4">
<title>Jurassic World</title>
<artist>Chris Pratt</artist>
</cd11>
</catalogue>
</publisher>
</root>
解释:
阅读并了解 <xsl:element> 指令。
阅读并了解 namespace-uri() 函数。
阅读并了解 <xsl:next-match> 指令。很少有人知道这条指令,也不知道它有多么强大和有用。