我有这份文件。
<?xml version="1.0" encoding="UTF-8"?>
<file>
<dummy_content>Contextual content<uicontrol>Mappings</uicontrol>More content</dummy_content>
<dummy_content>Contextual content<uicontrol>Code in</uicontrol>More content</dummy_content>
<dummy_content>Contextual content<uicontrol>Name</uicontrol>More content</dummy_content>
<dummy_content>Contextual content<uicontrol>Code out</uicontrol>More content</dummy_content>
<dummy_content>Contextual content<uicontrol>Mapping mode</uicontrol>More content</dummy_content>
<dummy_content>Contextual content<uicontrol>Change</uicontrol>More content</dummy_content>
<dummy_content>Contextual content<uicontrol>OK</uicontrol>More content</dummy_content>
<dummy_content>Contextual content<uicontrol>Add</uicontrol>More content</dummy_content>
<dummy_content>Contextual content<uicontrol>Edit</uicontrol>More content</dummy_content>
<dummy_content>Contextual content<uicontrol>Add/Update</uicontrol>More content</dummy_content>
</file>
我有一个文件,其中包含对这些UI控件的引用:
<?xml version="1.0" encoding="UTF-8"?>
<!-- DICT_min.xml -->
<DICTIONARY>
<DICT_ENTRY DICT_ID="ui58384" DICT_STRING="Reset target"/>
<DICT_ENTRY DICT_ID="ui16245" DICT_STRING="Mappings"/>
<DICT_ENTRY DICT_ID="ui56897" DICT_STRING="Mappings"/>
<DICT_ENTRY DICT_ID="ui56841" DICT_STRING="Code in"/>
<DICT_ENTRY DICT_ID="ui56850" DICT_STRING="Code in"/>
<DICT_ENTRY DICT_ID="ui56868" DICT_STRING="Code in"/>
<DICT_ENTRY DICT_ID="ui56869" DICT_STRING="Code out"/>
<DICT_ENTRY DICT_ID="ui56919" DICT_STRING="Add/Update"/>
<DICT_ENTRY DICT_ID="ui56920" DICT_STRING="Add/Update"/>
<DICT_ENTRY DICT_ID="dml3152" DICT_STRING="Retrieved"/>
<DICT_ENTRY DICT_ID="dml3261" DICT_STRING="Sent"/>
</DICTIONARY>
理想情况下,我希望将它们组合在一起:以便id属性位于原始文件中。有点棘手,因为每个可能的字符串通常有多个ID。但是,如果我有多个元素,它将帮助用户,因为它们更容易删除错位的元素,而不是键入正确的属性。所以我的目标就是这个。
<?xml version="1.0" encoding="UTF-8"?>
<file>
<dummy_content>Contextual content
<uicontrol ref="ui16245">Mappings</uicontrol>
<uicontrol ref="ui56897">Mappings</uicontrol>More content</dummy_content>
<dummy_content>Contextual content
<uicontrol ref="ui56841">Code in</uicontrol>
<uicontrol ref="ui56850">Code in</uicontrol>
<uicontrol ref="ui56868">Code in</uicontrol>More content</dummy_content>
<dummy_content>Contextual content<uicontrol>Name</uicontrol>More content</dummy_content>
<dummy_content>Contextual content<uicontrol ref="ui56869">Code out</uicontrol>More content</dummy_content>
<dummy_content>Contextual content<uicontrol>Mapping mode</uicontrol>More content</dummy_content>
<dummy_content>Contextual content<uicontrol>Change</uicontrol>More content</dummy_content>
<dummy_content>Contextual content<uicontrol>OK</uicontrol>More content</dummy_content>
<dummy_content>Contextual content<uicontrol>Add</uicontrol>More content</dummy_content>
<dummy_content>Contextual content<uicontrol>Edit</uicontrol>More content</dummy_content>
<dummy_content>Contextual content
<uicontrol ref="ui56919">Add/Update</uicontrol>
<uicontrol ref="ui56920">Add/Update</uicontrol>More content</dummy_content>
</file>
我一直在尝试大量的xslt命令。在我的天真和愚蠢中,我所拥有的最新想法是:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:variable name="dictstrings" select="document('DICT_min.xml')"/>
<xsl:key name="ui_ids" match="DICT_ENTRY" use="@DICT_STRING"/>
<!--Identity template, copies all content -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!--Template for uicontrol that provides custom behavior -->
<xsl:template match="uicontrol">
<xsl:variable name="uistring" select="."/>
<xsl:apply-templates select="$dictstrings">
<xsl:with-param name="uistring" select="$uistring"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="DICT_ENTRY">
<xsl:param name="uistring"/>
<xsl:for-each select="key('ui_ids',$uistring)">
<xsl:element name="uicontrol">
<xsl:attribute name="ref">
<xsl:value-of select="@DICT_ID"/>
</xsl:attribute>
<xsl:value-of select="@DICT_STRING"/>
</xsl:element>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
由于你知识渊博且观察力很强(我不是),因此产生了这个:
<?xml version="1.0" encoding="UTF-8"?>
<file>
<dummy_content>Contextual content<DICTIONARY/>More content</dummy_content>
<dummy_content>Contextual content<DICTIONARY/>More content</dummy_content>
...
你知道为什么我的上下文搞砸了,尝试访问外部DICT_min.xml文件吗?如何控制上下文,以便xsl和xpath知道要搜索哪个文件?
你有更好的建议吗?
答案 0 :(得分:1)
而不是<xsl:apply-templates select="$dictstrings">
使用<xsl:apply-templates select="key('ui_ids', ., $dictstrings)">
。
然后你的模板应该是
<xsl:template match="DICT_ENTRY">
<uicontrol ref="{@DICT_ID}">
<xsl:value-of select="@DICT_STRING"/>
</uicontrol>
</xsl:template>
答案 1 :(得分:1)
以这种方式试试吗?
XSLT 2.0
<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="*"/>
<xsl:param name="dictstrings" select="document('DICT_min.xml')"/>
<xsl:key name="dict_entry" match="DICT_ENTRY" use="@DICT_STRING"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="uicontrol[key('dict_entry', ., $dictstrings)]">
<xsl:apply-templates select="key('dict_entry', ., $dictstrings)"/>
</xsl:template>
<xsl:template match="DICT_ENTRY">
<uicontrol ref="{@DICT_ID}">
<xsl:value-of select="@DICT_STRING"/>
</uicontrol>
</xsl:template>
</xsl:stylesheet>