Xml 使用XSLT将元素更改为属性并缩短名称
我有一个需要转换的场景:Xml 使用XSLT将元素更改为属性并缩短名称,xml,xslt,transform,jaxp,Xml,Xslt,Transform,Jaxp,我有一个需要转换的场景: <Hand id="left"> <FingerOne>Thumb</FingerOne> <FingerTwo>Pointer</FingerTwo> <FingerThree>Middle</FingerThree> </Hand> 拇指 指针 中间的 致: 我一直在使用这段XSLT将嵌套的实体标记转换为属性,这非常有效。我不知道如何将名
<Hand id="left">
<FingerOne>Thumb</FingerOne>
<FingerTwo>Pointer</FingerTwo>
<FingerThree>Middle</FingerThree>
</Hand>
拇指
指针
中间的
致:
我一直在使用这段XSLT将嵌套的实体标记转换为属性,这非常有效。我不知道如何将名称“FingerOne”更改为1,“FingerTwo”更改为2,等等。不过,在将元素移动到属性中时
<xsl:for-each select="*">
<xsl:attribute name="{name()}">
<xsl:value-of select="text()"/>
</xsl:attribute>
</xsl:for-each>
我找到了这个答案,它展示了如何使用基本上是地图的东西来进行转换。但我似乎无法在我的文档中使用它
注意,我正试图使用JAXP在Java的内置XSLT功能中实现这一点。它似乎不支持很多XSLT2.0功能,因此如果您能坚持使用XSLT1.0,我将不胜感激。如果您想使用字典方法,您应该首先在名为
dict.xml的文件中创建字典:
<dict>
<entry name="FingerOne">F1</entry>
<entry name="FingerTwo">F2</entry>
<entry name="FingerThree">F3</entry>
</dict>
一层楼
地上二层
F3
然后您可以这样编写转换:
<xsl:variable name="dict" select="document('dict.xml')/dict"/>
<xsl:template match="Hand">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="*" mode="map-to-attr"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*" mode="map-to-attr">
<xsl:attribute name="{$dict/entry[@name=name(current())]}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
如果要使用字典方法,应首先在名为dict.xml的文件中创建字典:
<dict>
<entry name="FingerOne">F1</entry>
<entry name="FingerTwo">F2</entry>
<entry name="FingerThree">F3</entry>
</dict>
一层楼
地上二层
F3
然后您可以这样编写转换:
<xsl:variable name="dict" select="document('dict.xml')/dict"/>
<xsl:template match="Hand">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="*" mode="map-to-attr"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*" mode="map-to-attr">
<xsl:attribute name="{$dict/entry[@name=name(current())]}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
这里有一个自包含的选项,不需要任何外部XML文件
当此XSLT:
<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my"
exclude-result-prefixes="my"
version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:attributeNames>
<name original="FingerOne" new="F1"/>
<name original="FingerTwo" new="F2"/>
<name original="FingerThree" new="F3"/>
</my:attributeNames>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Hand/*">
<xsl:attribute
name="{document('')/*/my:attributeNames/*
[@original = name(current())]/@new}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
<Hand id="left">
<FingerOne>Thumb</FingerOne>
<FingerTwo>Pointer</FingerTwo>
<FingerThree>Middle</FingerThree>
</Hand>
<Hand id="left" F1="Thumb" F2="Pointer" F3="Middle" />
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vStartingChar" select="'F'" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Hand/*">
<xsl:attribute
name="{concat($vStartingChar, count(preceding-sibling::*) + 1)}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
<Hand id="left" F1="Thumb" F2="Pointer" F3="Middle" />
…应用于相同的输入XML,同样会生成想要的结果:
<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my"
exclude-result-prefixes="my"
version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:attributeNames>
<name original="FingerOne" new="F1"/>
<name original="FingerTwo" new="F2"/>
<name original="FingerThree" new="F3"/>
</my:attributeNames>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Hand/*">
<xsl:attribute
name="{document('')/*/my:attributeNames/*
[@original = name(current())]/@new}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
<Hand id="left">
<FingerOne>Thumb</FingerOne>
<FingerTwo>Pointer</FingerTwo>
<FingerThree>Middle</FingerThree>
</Hand>
<Hand id="left" F1="Thumb" F2="Pointer" F3="Middle" />
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vStartingChar" select="'F'" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Hand/*">
<xsl:attribute
name="{concat($vStartingChar, count(preceding-sibling::*) + 1)}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
<Hand id="left" F1="Thumb" F2="Pointer" F3="Middle" />
说明:
<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my"
exclude-result-prefixes="my"
version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:attributeNames>
<name original="FingerOne" new="F1"/>
<name original="FingerTwo" new="F2"/>
<name original="FingerThree" new="F3"/>
</my:attributeNames>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Hand/*">
<xsl:attribute
name="{document('')/*/my:attributeNames/*
[@original = name(current())]/@new}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
<Hand id="left">
<FingerOne>Thumb</FingerOne>
<FingerTwo>Pointer</FingerTwo>
<FingerThree>Middle</FingerThree>
</Hand>
<Hand id="left" F1="Thumb" F2="Pointer" F3="Middle" />
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vStartingChar" select="'F'" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Hand/*">
<xsl:attribute
name="{concat($vStartingChar, count(preceding-sibling::*) + 1)}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
<Hand id="left" F1="Thumb" F2="Pointer" F3="Middle" />
注意XSLT顶部定义的变量:
<xsl:variable name="vStartingChar" select="'F'" />
这提供了一种方便的机制来更改新属性的起始字符。如前所述,如果继续使用相同的模式(即,附加属性将遵循相同的方案-F4
,F5
,等等),此解决方案会更好,因为它不需要您更新元素的“数组”。这里有一个自包含且不需要任何外部XML文件的选项
当此XSLT:
<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my"
exclude-result-prefixes="my"
version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:attributeNames>
<name original="FingerOne" new="F1"/>
<name original="FingerTwo" new="F2"/>
<name original="FingerThree" new="F3"/>
</my:attributeNames>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Hand/*">
<xsl:attribute
name="{document('')/*/my:attributeNames/*
[@original = name(current())]/@new}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
<Hand id="left">
<FingerOne>Thumb</FingerOne>
<FingerTwo>Pointer</FingerTwo>
<FingerThree>Middle</FingerThree>
</Hand>
<Hand id="left" F1="Thumb" F2="Pointer" F3="Middle" />
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vStartingChar" select="'F'" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Hand/*">
<xsl:attribute
name="{concat($vStartingChar, count(preceding-sibling::*) + 1)}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
<Hand id="left" F1="Thumb" F2="Pointer" F3="Middle" />
…应用于相同的输入XML,同样会生成想要的结果:
<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my"
exclude-result-prefixes="my"
version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:attributeNames>
<name original="FingerOne" new="F1"/>
<name original="FingerTwo" new="F2"/>
<name original="FingerThree" new="F3"/>
</my:attributeNames>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Hand/*">
<xsl:attribute
name="{document('')/*/my:attributeNames/*
[@original = name(current())]/@new}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
<Hand id="left">
<FingerOne>Thumb</FingerOne>
<FingerTwo>Pointer</FingerTwo>
<FingerThree>Middle</FingerThree>
</Hand>
<Hand id="left" F1="Thumb" F2="Pointer" F3="Middle" />
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vStartingChar" select="'F'" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Hand/*">
<xsl:attribute
name="{concat($vStartingChar, count(preceding-sibling::*) + 1)}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
<Hand id="left" F1="Thumb" F2="Pointer" F3="Middle" />
说明:
<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my"
exclude-result-prefixes="my"
version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:attributeNames>
<name original="FingerOne" new="F1"/>
<name original="FingerTwo" new="F2"/>
<name original="FingerThree" new="F3"/>
</my:attributeNames>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Hand/*">
<xsl:attribute
name="{document('')/*/my:attributeNames/*
[@original = name(current())]/@new}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
<Hand id="left">
<FingerOne>Thumb</FingerOne>
<FingerTwo>Pointer</FingerTwo>
<FingerThree>Middle</FingerThree>
</Hand>
<Hand id="left" F1="Thumb" F2="Pointer" F3="Middle" />
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vStartingChar" select="'F'" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Hand/*">
<xsl:attribute
name="{concat($vStartingChar, count(preceding-sibling::*) + 1)}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
<Hand id="left" F1="Thumb" F2="Pointer" F3="Middle" />
注意XSLT顶部定义的变量:
<xsl:variable name="vStartingChar" select="'F'" />
这提供了一种方便的机制来更改新属性的起始字符。如前所述,如果继续使用相同的模式(即,附加属性将遵循相同的方案-F4
,F5
,等等),此解决方案的效果会更好,因为它不需要您更新元素的“数组”