我正在尝试解析文件manager.xml以获得我需要的正确数据结构。 manager.xml的示例:
<?xml version="1.0" encoding="koi8-r"?>
<manager>
<priv id="pr.screen.access" caption="c.screen.access">
<priv id="pr.screen.category.documents" caption="c.main.documents">
<priv id="pr.screen.category.documents.rcn" caption="c.main.documents.rcn">
<priv id="pr.screen.category.documents.rcn.create" caption="c.main.documents.rcn.create"/>
</priv>
</priv>
</priv>
<priv id="pr.screen.category.archives" caption="c.main.archives"/>
<priv id="pr.screen.category.documents.rcn.create_as" caption="c.main.documents.rcn.create_as" parent="pr.screen.access"/>
<priv id="pr.screen.category.transport_management.documents" caption="c.main.transport_management.documents"/>
<caption id="c.screen.access">
<loctext lang="ru" long="access"/>
</caption>
<caption id="c.main.documents">
<loctext lang="ru" long="documents"/>
</caption>
<caption id="c.main.documents.rcn">
<loctext lang="ru" long="rcn"/>
</caption>
<caption id="c.main.documents.rcn.create">
<loctext lang="ru" long="rcn_create"/>
</caption>
<caption id="c.main.archives">
<loctext lang="ru" long="archives"/>
</caption>
<caption id="c.main.documents.rcn.create_as">
<loctext lang="ru" long="rcn_create-as"/>
</caption>
<caption id="c.main.transport_management.documents">
<loctext lang="ru" long="transport_documents"/>
</caption>
</manager>
基本上我需要使用所有嵌套元素复制所有“priv”元素,并且还要找到具有“parent”属性的“priv”元素,并将其放入相应的“priv”元素,其中“id”属性等于“parent”。 / p>
除此之外,我还需要为每个“priv”元素添加“caption_ru”属性,其值从“loctext”元素的属性“long”获取,该元素位于“caption”元素内,其中“id”属性等于“标题“priv”的属性。这部分是有效的,但是有没有机会通过使用xsl:key函数来解决它?
我有下一个xslt,它几乎按照预期工作,但是我遇到了额外的“priv”元素,这是我在转换后获得的,我找不到任何方法来摆脱它们: XSL:
<?xml version="1.0" encoding="koi8-r"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="koi8-r" version="1.0"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:attribute name='caption_ru'>
<xsl:value-of select="//manager/caption[@id=current()/@caption]/loctext[@lang='ru']/@long"/>
</xsl:attribute>
<xsl:apply-templates select="@* | priv[not(@parent)]"/>
<xsl:call-template name="nested_priv"/>
<!--xsl:copy>
<xsl:apply-templates select="//manager/priv[@parent=current()/@id]"/>
</xsl:copy-->
</xsl:copy>
</xsl:template>
<xsl:template name="nested_priv">
<xsl:copy>
<!--xsl:attribute name='caption_ru'>
<xsl:value-of select="//manager/caption[@id=current()/@caption]/loctext[@lang='ru']/@long"/>
</xsl:attribute-->
<xsl:apply-templates select="//manager/priv[@parent=current()/@id]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这是我在转型后获得的:
<?xml version="1.0" encoding="koi8-r"?>
<manager caption_ru="">
<priv caption_ru="access" id="pr.screen.access" caption="c.screen.access">
<priv caption_ru="documents" id="pr.screen.category.documents" caption="c.main.documents">
<priv caption_ru="rcn" id="pr.screen.category.documents.rcn" caption="c.main.documents.rcn">
<priv caption_ru="rcn_create" id="pr.screen.category.documents.rcn.create" caption="c.main.documents.rcn.create">
<priv/>
</priv>
<priv/>
</priv>
<priv/>
</priv>
<priv>
<priv caption_ru="rcn_create-as" id="pr.screen.category.documents.rcn.create_as" caption="c.main.documents.rcn.create_as" parent="pr.screen.access">
<priv/>
</priv>
</priv>
</priv>
<priv caption_ru="archives" id="pr.screen.category.archives" caption="c.main.archives">
<priv/>
</priv>
<priv caption_ru="transport_documents" id="pr.screen.category.transport_management.documents" caption="c.main.transport_management.documents">
<priv/>
</priv>
<manager/>
</manager>
答案 0 :(得分:0)
这样怎么样?
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="koi8-r" indent="yes"/>
<xsl:key name="caption" match="caption" use="@id" />
<xsl:template match="/manager">
<xsl:copy>
<xsl:apply-templates select="priv"/>
</xsl:copy>
</xsl:template>
<xsl:template match="priv">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:attribute name="caption_ru">
<xsl:value-of select="key('caption', @caption)/loctext/@long" />
</xsl:attribute>
<xsl:apply-templates select="priv"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
已解决上面列出的xsl,这是基于user3016153的回答,我非常感谢。我不确定我是否应该接受他的回答,但我做了,因为它非常有帮助。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="koi8-r" indent="yes"/>
<xsl:key name="caption" match="caption" use="@id" />
<xsl:key name="child_priv" match="priv" use="@parent"/>
<xsl:template match="/manager">
<xsl:copy>
<xsl:apply-templates select="priv[not(@parent)]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="priv">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:attribute name="caption_ru">
<xsl:value-of select="key('caption', @caption)/loctext[@lang='ru']/@long" />
</xsl:attribute>
<xsl:apply-templates select="priv"/>
<xsl:apply-templates select="key('child_priv',current()/@id)"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>