删除xml文件中的所有特定节点

时间:2015-08-17 13:21:52

标签: xml

我有一个非常大的xml文件(确切地说是347496行),它包含许多具有我需要删除的特定属性的元素。元素的内容不同,因此查找/替换不起作用。是否有一个程序可以为我删除所有元素,或者至少有一个教程,它会教我编写程序脚本来执行此操作?

其中一个元素的示例:http://pastebin.com/ECq42NE2

元素是Item,class属性是“ManualWeld”

3 个答案:

答案 0 :(得分:0)

创建简单的控制台应用。

请试试这个C#代码:

using (var reader = XmlReader.Create("input.xml"))
using (var writer = XmlWriter.Create("output.xml"))
{
    while (reader.Read())
    {
        switch (reader.NodeType)
        {
            case XmlNodeType.Element:
                if (reader.Name == "Item")
                {
                    if (reader.MoveToAttribute("class") && reader.Value == "ManualWeld")
                    {
                        reader.Skip();
                        break;
                    }
                }
                writer.WriteStartElement(reader.Name);
                break;
            case XmlNodeType.Text:
                writer.WriteString(reader.Value);
                break;
            case XmlNodeType.Whitespace:
            case XmlNodeType.SignificantWhitespace:
                writer.WriteWhitespace(reader.Value);
                break;
            case XmlNodeType.XmlDeclaration:
            case XmlNodeType.ProcessingInstruction:
                writer.WriteProcessingInstruction(reader.Name, reader.Value);
                break;
            case XmlNodeType.CDATA:
                writer.WriteCData(reader.Value);
                break;
            case XmlNodeType.Comment:
                writer.WriteComment(reader.Value);
                break;
            case XmlNodeType.Attribute:
                writer.WriteAttributes(reader, true);
                break;
            case XmlNodeType.EntityReference:
                writer.WriteEntityRef(reader.Value);
                break;
            case XmlNodeType.EndElement:
                writer.WriteFullEndElement();
                break;
        }
    }
}

我们需要手动复制所有节点,排除属性。

答案 1 :(得分:0)

这对于XSL转换(XSLT)来说是一项微不足道的任务:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
    </xsl:template>

    <xsl:template match="Item[@class='ManualWeld']" />      
</xsl:stylesheet>

简要说明:

  • <xsl:output indent="yes"/>:使用适当的缩进格式输出[MSDN]。
  • <xsl:strip-space elements="*"/>:剥离可能出现在元素属性[MSDN]指定的元素中的仅限空格的文本节点。
  • <xsl:template match="node()|@*">...</xsl:template>:身份模板。将匹配的节点和属性复制到输出XML,不变。
  • <xsl:template match="Item[@class='ManualWeld']" />:覆盖属性Item值等于class的{​​{1}}个元素的身份模板。这是一个空模板,意味着匹配的元素不会被复制到输出XML(更一般地,空模板不会对匹配的元素进行任何操作)。

<强> Xsltransform Demo

请在演示输出中注意,"ManualWeld"元素已删除Item元素,其他元素(class='ManualWeld'和另一个root元素)将被保留。

答案 2 :(得分:0)

我解决了问题,但没有按照你预期的方式解决。看到这是一个充满了ManualWelds和Welds的roblox地方的xml文件,它一直保持着一切。所以我写了一个简单的Lua插件,删除了Workspace中的所有焊缝。

local plugin = PluginManager():CreatePlugin()
local toolbar = plugin:CreateToolbar("Remove Welds Plugin")

local button = toolbar:CreateButton(
    "Remove All Welds", 
    "Click this button to remove all welds",
    "button.png"
)

function RemoveWelds(location)
        for _, v in pairs(location:GetChildren()) do
            if v:isA("Weld") or v:isA("ManualWeld") then 
                v:remove() 
                print("Removed " .. v:GetFullName())
            else
                RemoveWelds(v)
            end
     end
end

button.Click:connect(function()
    RemoveWelds(workspace)
end)