我实际上很难描述标题,所以让我告诉你我的内容:
我的XML最初是一个平面文件,已经转换为XML供我使用。下面是对原始XML的简化:
<Elements>
<ElementBegin value="e1"/>
<ElementBegin value="e2"/>
<String>Some Blabla</String>
<ElementEnd value="e2"/>
<ElementBegin value="e2"/>
<String>Some other Blabla</String>
<ElementEnd value="e2"/>
<ElementBegin value="e5"/>
<String>Some more Blabla</String>
<ElementEnd value="e5"/>
<ElementEnd value="e1"/>
</Elements>
是否可以使用正则表达式或其他方式简单地将<ElementBegin value="e1"/>
重命名为<e1>
和<ElementEnd value="e1"/>
至</e1>
?或任何其他方法可行吗?
所以最后的结果变成了
<Elements>
<e1>
<e2>
<String>Some Blabla</String>
</e2>
<e2>
<String>Some other Blabla</String>
</e2>
<e5>
<String>Some more Blabla</String>
</e5>
</e1>
</Elements>
提前致谢!
答案 0 :(得分:3)
使用XSLT简单地重命名元素不需要正则表达式。你可以简单地做这样的事情:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<!-- Identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- Drop @value attribute -->
<xsl:template match="@value"/>
<!-- Rename <ElementBegin> and <ElementEnd> -->
<xsl:template match="ElementBegin | ElementEnd">
<!-- Use the value of the @value attribute as the new element name -->
<xsl:element name="{@value}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
但是,您的输入XML与您希望实现的内容之间存在一些差异。使用上面的样式表将产生以下结果:
<?xml version="1.0"?>
<Elements>
<e1/>
<e2/>
<String>Some Blabla</String>
<e2/>
<e2/>
<String>Some other Blabla</String>
<e2/>
<e5/>
<String>Some more Blabla</String>
<e5/>
<e1/>
</Elements>
我认为,这不是你想要的。要实现正确的嵌套,您需要一个更复杂的样式表。这样的东西应该有效(XSLT1.0兼容):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<!-- Copy <String> elements as is -->
<xsl:template match="String">
<xsl:copy>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>
<xsl:template match="Elements">
<xsl:copy>
<!-- Apply the first <ElementBegin> element -->
<xsl:apply-templates select="ElementBegin[1]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ElementBegin">
<!-- Use the value of the @value attribute as the new element name -->
<xsl:element name="{@value}">
<!--
Apply String elements whose first preceding <ElementBegin>
sibling is the current element
-->
<xsl:apply-templates select="following-sibling::String
[preceding-sibling::ElementBegin[1]
[generate-id() = generate-id(current())]]"/>
</xsl:element>
</xsl:template>
<!--
Process <ElementBegin value="e1">. You could also use "ElementBegin[1]".
-->
<xsl:template match="ElementBegin[@value = 'e1']">
<xsl:element name="{@value}">
<!-- Apply all following <ElementBegin> siblings -->
<xsl:apply-templates select="following-sibling::ElementBegin"/>
</xsl:element>
</xsl:template>
<!-- Drop <ElementEnd> elements -->
<xsl:template match="ElementEnd"/>
</xsl:stylesheet>
<?xml version="1.0"?>
<Elements>
<e1>
<e2>
<String>Some Blabla</String>
</e2>
<e2>
<String>Some other Blabla</String>
</e2>
<e5>
<String>Some more Blabla</String>
</e5>
</e1>
</Elements>
答案 1 :(得分:2)
我不知道xslt,但正则表达式可以很容易地完成这项任务。以下是使用Perl语法的示例:
s|<ElementBegin value="(\w+)"/>|<$1>|g;
s|<ElementEnd value="(\w+)"/>|</$1>|g;
答案 2 :(得分:2)
<?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" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ElementBegin">
<xsl:value-of select="concat('<', @value,'>')" disable-output-escaping="yes"/>
</xsl:template>
<xsl:template match="ElementEnd">
<xsl:value-of select="concat('</', @value,'>')" disable-output-escaping="yes"/>
</xsl:template>
</xsl:stylesheet>
<强>解释强>
<xsl:template match="ElementBegin">
<xsl:value-of select="concat('<', @value,'>')" disable-output-escaping="yes"/>
</xsl:template>
以上模板创建一个新的开放标记,其元素名称为@value,
示例:<e1>
和..
<xsl:template match="ElementEnd">
<xsl:value-of select="concat('</', @value,'>')" disable-output-escaping="yes"/>
</xsl:template>
此代码创建一个新的闭合标记,其元素名称为属性值的值。
实施例:</e1>
所以你的输出XML看起来像这样:
<Elements>
<e1>
<e2>
<String>Some Blabla</String>
</e2>
<e2>
<String>Some other Blabla</String>
</e2>
<e5>
<String>Some more Blabla</String>
</e5>
</e1>
</Elements>
答案 3 :(得分:1)
结合了Begin和End的正则表达式:
<Element(?|Begin[^"]+"(\w+)"\/()|End[^"]+"(\w+)"(\/))
并替换为<\2\1
在此解释演示:http://regex101.com/r/nA9rA8