我有一个XML文件,其中包含自定义标记包含的大量数据。这对我所拥有的一个项目都很有用,但对于另一个项目我不需要那么多信息。因此,我想修剪XML文件,并删除某些标记的所有实例以及标记之间的任何内容。
<GOBJ>
<cost>4</cost>
<duration>n/a</duration>
<item>Stone Block</item>
<type>Construction - Material</type>
<misc>Use these blocks to build things. These blocks don't degrade.</misc>
</GOBJ>
我只想保留[item]blah[item]
和[type]blah[type]
,其余内容应删除/删除。
稍后,我需要检查[type]
的文本,如果它与某些单词匹配,则替换其内容。例如,如果单词metal位于[type]
标记内的任何位置,则将该标记的内容替换为单词metal。
我知道这是一个很大的要求;我感谢任何帮助。
答案 0 :(得分:2)
另一种方法是使用简单的XML→XML(带有XPath 1.0的XSLT 1.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" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="root">
<root>
<xsl:apply-templates select="GOBJ"/>
</root>
</xsl:template>
<xsl:template match="GOBJ">
<GOBJ>
<xsl:copy-of select="item"/>
<type>
<xsl:choose>
<xsl:when test="contains(type, 'metal')">
<xsl:text>metal</xsl:text>
</xsl:when>
<!-- other xsl:when conditions here -->
<xsl:otherwise>
<xsl:value-of select="type"/>
</xsl:otherwise>
</xsl:choose>
</type>
</GOBJ>
</xsl:template>
</xsl:stylesheet>
我知道它不是基于正则表达式的解决方案,但恕我直言,最好使用原生的面向XML的工具包。
答案 1 :(得分:0)
假设文件的布局与您的示例完全相同,则乘以所需数量的记录,并希望尽可能保留原始布局,替换
(<GOBJ>[^<]+?).+?(<item>.+?<\/type>\n).+?(<\/GOBJ>)
与
$1$2$3
全局并且正则表达式设置为以“单行”模式运行,将执行您需要的iff,元素<GOBJ>
为大写,其他元素为小写,每个记录每个元素只有一个实例,元素<item>
始终显示在每个记录中元素<type>
之前。
在JavaScript中,这将是:
var result = src.replace(
/(<GOBJ>[^<]+?).+?(<item>.+?<\/type>\n).+?(<\/GOBJ>)/g,
'$1$2$3'
);
请注意,严格条件可以缓解与使用正则表达式解析XML相关的任何问题。如果无法满足条件,那么使用特定于XML的工具(如XSLT)可以提供更好的服务。
答案 2 :(得分:0)
这是一个grep解决方案:grep -E '(<item>|<type>)' myfile.xml
答案 3 :(得分:0)
我开发了另一种解决问题的方法;我构建了一个jquery脚本,它分割了xml代码(我用手前的不同符号替换了所有左/右箭头),如果我没有包含另一个特定符号,则输出数组条目。
var name = $('div').text().trim().split(/\[name\](.*?)\[\/name\]/g);
var type = $('div').text().trim().split(/\[type\](.*?)\[\/type\]/g);
for (i = 0; name.length > i; i++) {
if ((type[i].match(/\[/g))) {
type[i] = "";
}
if (!(name[i].match(/\[/g))) {
if (type[i].match(/construction/g)) {type[i] = "T_C";}
if (type[i].match(/material/g)) {type[i] = "T_M";}
if (type[i].match(/metalwork/g)) {type[i] = "T_W";}
if (type[i].match(/water/g)) {type[i] = "T_W";}
if (type[i].match(/oil/g)) {type[i] = "T_O";}
if (type[i].match(/precious/g)) {type[i] = "T_P";}
if (type[i].match(/magic/g)) {type[i] = "T_M";}
$('.Collect').append('<p>a href="../Img/XXX/' + name[i] + '.jpg" class="' + type[i] + '">' + name[i] + '/a></p>');
} else {
name[i] = "";
}
}
输出的格式是这样的,这样我就可以将页面复制粘贴到txt / html文件中,并按照我想要的方式使用它。我将不得不想办法用适当的目录名替换XXX ...
我只需要做一次或两次,所以纯粹的自动化并不是必须的。
答案 4 :(得分:0)
如果要解析XML日志文件,以便可以使用正则表达式{java},if (changing_array == final_array)
{
Console.WriteLine("It took {0} passes to sort \n{1} \ninto \n{2} ", pass_count, starting_array, final_array);
sorted = true;
}
else
{
Console.WriteLine("End of pass {0}. \n{1} \nis now \n{2} ", pass_count, starting_array, changing_array);
break;//this is what will prevent infinite loop
}
。那么您将获得<[^<]+<
。输出类似于 name> DEV 。