我试图转换输入XML :
<?xml version="1.0" encoding="utf-8"?>
<request>
<customer_data>
<contact_info>
<name>john doe</name>
<dob_year>1984</dob_year>
<dob_month>09</dob_month>
<dob_date>14</dob_date>
<gender>m</gender>
</contact_info>
</customer_data>
</request>
所以它看起来像这样:
<?xml version="1.0" encoding="utf-8"?>
<request>
<customer_data>
<contact_info>
<name>john doe</name>
<dob>1984-09-14</dob>
<gender>m</gender>
</contact_info>
</customer_data>
</request>
以下是 XSLT ,我正在使用:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="contact_info">
<xsl:copy>
<dob>
<xsl:value-of select="(dob_year, dob_month, dob_date)" separator="-"/>
</dob>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这是我得到的结果:
<?xml version="1.0" encoding="utf-8"?><request>
<customer_data>
<contact_info><dob>1984-09-14</dob></contact_info>
</customer_data>
</request>
如何转换dob_ *标签,保持contact_info的其余部分完好无损?
更新
根据以下答案,我目前的解决方案是
<xsl:template match="contact_info">
<xsl:copy>
<xsl:apply-templates select="*[not(starts-with(name(), 'dob'))]"/>
<dob>
<xsl:value-of select="(dob_year, dob_month, dob_date)" separator="-"/>
</dob>
</xsl:copy>
</xsl:template>
这对我有用,但是没有更优雅的方式表达&#34; 将转换应用于给定元素,并将模板应用于其余&#34;?现在,我有点坚持使用这个表达式*[not(starts-with(name(), 'dob'))]
并不是那么糟糕,但是如果&#34; DOB&#34;属性改变了,我也必须解决这个问题。
答案 0 :(得分:1)
更改
<xsl:template match="contact_info">
<xsl:copy>
<dob>
<xsl:value-of select="(dob_year, dob_month, dob_date)" separator="-"/>
</dob>
</xsl:copy>
</xsl:template>
到
<xsl:template match="contact_info">
<xsl:copy>
<xsl:apply-templates select="dob_year/preceding-sibling::node()"/>
<dob>
<xsl:value-of select="(dob_year, dob_month, dob_date)" separator="-"/>
</dob>
<xsl:apply-templates select="dob_date/following-sibling::node()"/>
</xsl:copy>
</xsl:template>
答案 1 :(得分:1)
这是你可以看到它的一种方式:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<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="dob_year">
<dob>
<xsl:value-of select="(., ../dob_month, ../dob_date)" separator="-"/>
</dob>
</xsl:template>
<xsl:template match="dob_month|dob_date"/>
</xsl:stylesheet>
这是另一个:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<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="contact_info">
<xsl:copy>
<xsl:copy-of select="name|gender"/>
<dob>
<xsl:value-of select="(dob_year, dob_month, dob_date)" separator="-"/>
</dob>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
为了仅枚举DOB元素并且只进行一次,您可以这样做:
<xsl:template match="contact_info">
<xsl:variable name="dob-fields" select="(dob_year, dob_month, dob_date)" />
<xsl:copy>
<xsl:apply-templates select="* except $dob-fields"/>
<dob>
<xsl:value-of select="$dob-fields" separator="-"/>
</dob>
</xsl:copy>
</xsl:template>