XML节点模板——我应该使用XSLT吗?
XML node template - should I use XSLT?
我有一个具有以下结构(多个"实体"节点)的XML文件:
<!-- entities.xml -->
<root>
<entity template="foo-template" kind="foo" name="bar">
<groups>
<group id="1">
<definition id="1" name="foobar" />
</group>
</groups>
</entity>
</root>
许多entity
节点具有相似的属性和子节点。我想让用户在一个单独的文件中创建entity
模板。引用模板的操作如下:
<entity template="foo-template" kind="foo" ... />
"foo-template"中的每个属性和子节点都应该复制到entity
中,除了那些已经存在的(即允许覆盖模板)。
我不太熟悉XSLT。它是完成这项任务的正确工具吗,还是我在没有它的情况下更好地实现它?
我正在使用c++和RapidXml,但可以使用其他XML库。
<
编辑:例子/strong>。
模板文件:
<!-- templates.xml -->
<templates>
<entity template="foo-template" name="n/a" model="baz">
<groups>
<group id="1">
<definition id="1" name="def1" />
<definition id="2" name="def2" />
</group>
<group id="2">
<definition id="1" name="def3" />
<definition id="2" name="def4" />
</group>
</groups>
</entity>
</templates>
输出文件:
<!-- output.xml -->
<root>
<entity kind="foo" name="bar" model="baz">
<groups>
<group id="1">
<definition id="1" name="foobar" />
</group>
<group id="2">
<definition id="1" name="def3" />
<definition id="2" name="def4" />
</group>
</groups>
</entity>
</root>
因此输出包含来自"entities.xml"的组1和来自"templates.xml"的组2。不需要合并相同id的group
节点。
如果你有一个文件templates.xml
看起来像
<templates>
<entity template="foo-template" kind="foo" name="bar" model="baz" />
<!-- and other entity elements with different template="..." values -->
</templates>
,那么像下面这样的XSLT将实现
之后的内容<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:key name="kEntityTemplate" match="entity" use="@template" />
<!-- identity template - copy everything not overridden by another template -->
<xsl:template match="@*|node">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
<xsl:template match="entity[@template]">
<xsl:variable name="thisEntity" select="." />
<!-- switch to templates doc -->
<xsl:for-each select="document('templates.xml')">
<xsl:variable name="template"
select="key('kEntityTemplate', $thisEntity/@template)" />
<entity>
<!-- copy template attributes that are not overridden -->
<xsl:for-each select="$template/@*">
<xsl:if test="not($thisEntity/@*[name() = name(current())])">
<!-- if not, copy the one from the template -->
<xsl:apply-templates select="." />
</xsl:if>
</xsl:for-each>
<!-- copy source attributes -->
<xsl:apply-templates select="$thisEntity/@*[name() != 'template']" />
<!-- deal with elements -->
<xsl:if test="$thisEntity/groups/group | $template/groups/group">
<groups>
<!-- here we select all group elements from the source plus
those group elements from the template that do not also exist
in the source, and sort the whole lot by id -->
<xsl:apply-templates select="$thisEntity/groups/group
| $template/groups/group[not(@id = $thisEntity/groups/group/@id)]">
<xsl:sort select="@id" data-type="number" />
</xsl:apply-templates>
</groups>
</xsl:if>
</entity>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
templates.xml
文件需要与样式表位于同一目录
除了进行任何类型的XML转换之外,还有一个选项是导入另一个XML文件,然后从标记中引用它。请看这里的例子。
这将要求您的用户为每种模板类型拥有单独的模板文件,这可能不是您想要的。然而,由于接吻原则,我更喜欢导入方法。如果您不熟悉XSLT,那么导入可能也是一种更好的方法。
我希望这对你有帮助!
相关文章:
- 我应该使用什么来代替void作为变体中的替代类型之一
- boost::asio::steady_timer()与sleep()我应该使用哪一个
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 我应该删除矢量<short>吗?
- 我应该如何修改此代码以使用给定字符串中的字母打印菱形图案
- 我应该在锁定TBitmap画布后解锁它吗
- 为什么我应该在异常处理中使用std::cerr而不是std::cout
- 我应该避免多重实现继承吗
- 为了方便起见,我应该避免公开私有字段变量吗
- 我收到同义重复编译器错误。我应该如何修复"类型"X"的参数与类型"X"的参数不兼容?
- 违反const正确性:我应该现实地期待什么问题
- 我应该如何表示我拥有的连续元素序列?
- 我应该将除 .cpp 以外的其他文件添加到 git 中吗?
- 我应该如何从 stdin C++ 中读取可变长度的格式字符串?
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 我应该如何捕捉out_of_range异常?
- 我应该声明所有不抛出 noexexcept 的成员/函数吗?
- OpenCV 我应该使用智能指针来防止内存泄漏吗?
- XML节点模板——我应该使用XSLT吗?