我是新来的,如果我做错了,请原谅。
我有一系列具有不同XML节点定义的不同XML文档。我正在尝试创建一个实用的控制台应用程序,它允许我将任何xml文件修剪为包含其中特定字符串值的节点。
例如这个xml:
<CWeaponInfoBlob>
<SlotNavigateOrder>
<Item>
<WeaponSlots>
<Item>
<OrderNumber value="10" />
<Entry>SLOT_UNARMED</Entry>
</Item>
<Item>
<OrderNumber value="20" />
<Entry>SLOT_KNIFE</Entry>
</Item>
<Item>
<OrderNumber value="30" />
<Entry>SLOT_NIGHTSTICK</Entry>
</Item>
<Item>
<OrderNumber value="40" />
<Entry>SLOT_HAMMER</Entry>
</Item>
<Item>
<OrderNumber value="50" />
<Entry>SLOT_BAT</Entry>
</Item>
<Item>
<OrderNumber value="60" />
<Entry>SLOT_CROWBAR</Entry>
</Item>
<Item>
<OrderNumber value="70" />
<Entry>SLOT_GOLFCLUB</Entry>
</Item>
<Item>
<OrderNumber value="90" />
<Entry>SLOT_PISTOL</Entry>
</Item>
<Item>
<OrderNumber value="100" />
<Entry>SLOT_COMBATPISTOL</Entry>
</Item>
<Item>
<OrderNumber value="110" />
<Entry>SLOT_PISTOL50</Entry>
</Item>
<Item>
<OrderNumber value="120" />
<Entry>SLOT_APPISTOL</Entry>
</Item>
<Item>
<OrderNumber value="130" />
<Entry>SLOT_STUNGUN</Entry>
</Item>
</WeaponSlots>
</Item>
</SlotNavigationOrder>
</CWeaponInfoBlob>
我希望能够像“STUNGUN”一样将字符串传递给控制台,并让程序删除任何不包含该字的“Item”节点。
我已经成功完成了这项工作,但并不像我希望的那样。我有一个包含21,615行的XML文件,其中包含“武器”的定义。通过将“STUNGUN”传递给控制台,我希望它能做同样的事情,并删除没有包含输入单词的节点的任何节点(我猜父节点)。
Here's my xml file 如果你搜索单词“STUNGUN”,你会发现它的多个定义,我希望程序只保留那些节点(和兄弟节点!! )。我该怎么做呢?
这是我尝试过的(不要判断代码,我在5年的编程中从未做过这样的事情,显然它不起作用):
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
namespace XmlUtil
{
class Program
{
static void Main(string[] args)
{
if (args.Length <= 0)
return;
if (!args.All(i => i.EndsWith(".meta")) && !args.All(i => i.EndsWith(".xml")))
return;
try
{
for (int x = 0; x < args.Length; x++)
{
var arg = args[x];
Console.WriteLine("Enter a string value:");
var userInput = Console.ReadLine();
var xml = new XmlDocument();
xml.Load(arg);
var nodes = xml.GetElementsByTagName("*");
var ienum = nodes.GetEnumerator();
XmlDocument newDoc = new XmlDocument();
while(ienum.MoveNext())
{
XmlNode node = (XmlNode)ienum.Current;
if (node.InnerText.Contains(userinput))
{
newDoc.ImportNode(node, false);
}
}
// Then write it to a file...
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
Console.ReadLine();
}
Console.WriteLine("Press [Enter] to exit...");
Console.ReadLine();
}
}
}
编辑:我想补充一点,这是手动完成的,我花了几个小时来剪掉不需要的节点。
<?xml version="1.0" encoding="UTF-8"?>
<CWeaponInfoBlob>
<SlotNavigateOrder>
<Item>
<WeaponSlots>
<Item>
<OrderNumber value="191" />
<Entry>SLOT_SCICARBINE</Entry>
</Item>
</WeaponSlots>
</Item>
<Item>
<WeaponSlots>
<Item>
<OrderNumber value="201" />
<Entry>SLOT_SCICARBINE</Entry>
</Item>
</WeaponSlots>
</Item>
</SlotNavigateOrder>
<SlotBestOrder>
<WeaponSlots>
<Item>
<OrderNumber value="81" />
<Entry>SLOT_SCICARBINE</Entry>
</Item>
</WeaponSlots>
</SlotBestOrder>
<TintSpecValues />
<FiringPatternAliases />
<UpperBodyFixupExpressionData />
<AimingInfos />
<Infos>
<Item>
<Infos>
<Item type="CWeaponInfo">
<Name>WEAPON_SCICARBINE</Name>
<Model>W_AR_SCICARBINERIFLE</Model>
<Audio>AUDIO_ITEM_RAILGUN</Audio>
<Slot>SLOT_SCICARBINE</Slot>
<DamageType>BULLET</DamageType>
<Explosion>
<Default>DONTCARE</Default>
<HitCar>DONTCARE</HitCar>
<HitTruck>DONTCARE</HitTruck>
<HitBike>DONTCARE</HitBike>
<HitBoat>DONTCARE</HitBoat>
<HitPlane>DONTCARE</HitPlane>
</Explosion>
<FireType>INSTANT_HIT</FireType>
<WheelSlot>WHEEL_RIFLE</WheelSlot>
<Group>GROUP_RIFLE</Group>
<AmmoInfo ref="AMMO_RIFLE" />
<AimingInfo ref="RIFLE_LO_BASE_STRAFE" />
<ClipSize value="30" />
<AccuracySpread value="3.000000" />
<AccurateModeAccuracyModifier value="0.500000" />
<RunAndGunAccuracyModifier value="2.000000" />
<RunAndGunAccuracyMaxModifier value="1.000000" />
<RecoilAccuracyMax value="0.500000" />
<RecoilErrorTime value="3.000000" />
<RecoilRecoveryRate value="1.000000" />
<RecoilAccuracyToAllowHeadShotAI value="1000.000000" />
<MinHeadShotDistanceAI value="1000.000000" />
<MaxHeadShotDistanceAI value="1000.000000" />
<HeadShotDamageModifierAI value="1000.000000" />
<RecoilAccuracyToAllowHeadShotPlayer value="0.175000" />
<MinHeadShotDistancePlayer value="5.000000" />
<MaxHeadShotDistancePlayer value="40.000000" />
<HeadShotDamageModifierPlayer value="18.000000" />
<Damage value="32.000000" />
<DamageTime value="0.000000" />
<DamageTimeInVehicle value="0.000000" />
<DamageTimeInVehicleHeadShot value="0.000000" />
<HitLimbsDamageModifier value="0.500000" />
<NetworkHitLimbsDamageModifier value="0.800000" />
<LightlyArmouredDamageModifier value="0.750000" />
<Force value="75.000000" />
<ForceHitPed value="140.000000" />
<ForceHitVehicle value="1200.000000" />
<ForceHitFlyingHeli value="1250.000000" />
<OverrideForces>
<Item>
<BoneTag>BONETAG_HEAD</BoneTag>
<ForceFront value="80.000000" />
<ForceBack value="50.000000" />
</Item>
<Item>
<BoneTag>BONETAG_NECK</BoneTag>
<ForceFront value="60.000000" />
<ForceBack value="90.000000" />
</Item>
<Item>
<BoneTag>BONETAG_L_THIGH</BoneTag>
<ForceFront value="40.000000" />
<ForceBack value="1.000000" />
</Item>
<Item>
<BoneTag>BONETAG_R_THIGH</BoneTag>
<ForceFront value="40.000000" />
<ForceBack value="1.000000" />
</Item>
<Item>
<BoneTag>BONETAG_L_CALF</BoneTag>
<ForceFront value="70.000000" />
<ForceBack value="80.000000" />
</Item>
<Item>
<BoneTag>BONETAG_R_CALF</BoneTag>
<ForceFront value="60.000000" />
<ForceBack value="100.000000" />
</Item>
</OverrideForces>
<ForceMaxStrengthMult value="1.000000" />
<ForceFalloffRangeStart value="0.000000" />
<ForceFalloffRangeEnd value="50.000000" />
<ForceFalloffMin value="1.000000" />
<ProjectileForce value="0.000000" />
<FragImpulse value="600.000000" />
<Penetration value="0.100000" />
<VerticalLaunchAdjustment value="0.000000" />
<DropForwardVelocity value="0.000000" />
<Speed value="2000.000000" />
<BulletsInBatch value="1" />
<BatchSpread value="0.000000" />
<ReloadTimeMP value="-1.000000" />
<ReloadTimeSP value="-1.000000" />
<VehicleReloadTime value="1.000000" />
<AnimReloadRate value="1.000000" />
<BulletsPerAnimLoop value="1" />
<TimeBetweenShots value="0.135000" />
<TimeLeftBetweenShotsWhereShouldFireIsCached value="-1.000000" />
<SpinUpTime value="0.000000" />
<SpinTime value="0.000000" />
<SpinDownTime value="0.000000" />
<AlternateWaitTime value="-1.000000" />
<BulletBendingNearRadius value="0.000000" />
<BulletBendingFarRadius value="0.750000" />
<BulletBendingZoomedRadius value="0.375000" />
<FirstPersonBulletBendingNearRadius value="0.000000" />
<FirstPersonBulletBendingFarRadius value="0.750000" />
<FirstPersonBulletBendingZoomedRadius value="0.375000" />
<Fx>
<EffectGroup>WEAPON_EFFECT_GROUP_RIFLE_ASSAULT</EffectGroup>
<FlashFx>muz_railgun</FlashFx>
<FlashFxAlt />
<FlashFxFP />
<FlashFxAltFP />
<MuzzleSmokeFx />
<MuzzleSmokeFxFP />
<MuzzleSmokeFxMinLevel value="0.000000" />
<MuzzleSmokeFxIncPerShot value="0.000000" />
<MuzzleSmokeFxDecPerSec value="0.000000" />
<ShellFx>eject_auto</ShellFx>
<ShellFxFP>eject_auto_fp</ShellFxFP>
<TracerFx>bullet_tracer</TracerFx>
<PedDamageHash>BulletLarge</PedDamageHash>
<TracerFxChanceSP value="0.150000" />
<TracerFxChanceMP value="0.750000" />
<FlashFxChanceSP value="1.000000" />
<FlashFxChanceMP value="1.000000" />
<FlashFxAltChance value="0.200000" />
<FlashFxScale value="1.000000" />
<FlashFxLightEnabled value="true" />
<FlashFxLightCastsShadows value="false" />
<FlashFxLightOffsetDist value="0.000000" />
<FlashFxLightRGBAMin x="255.000000" y="93.000000" z="25.000000" />
<FlashFxLightRGBAMax x="255.000000" y="100.000000" z="50.000000" />
<FlashFxLightIntensityMinMax x="1.000000" y="2.000000" />
<FlashFxLightRangeMinMax x="2.500000" y="3.500000" />
<FlashFxLightFalloffMinMax x="1024.000000" y="1536.000000" />
<GroundDisturbFxEnabled value="false" />
<GroundDisturbFxDist value="5.000000" />
<GroundDisturbFxNameDefault />
<GroundDisturbFxNameSand />
<GroundDisturbFxNameDirt />
<GroundDisturbFxNameWater />
<GroundDisturbFxNameFoliage />
</Fx>
<InitialRumbleDuration value="90" />
<InitialRumbleIntensity value="0.700000" />
<InitialRumbleIntensityTrigger value="0.950000" />
<RumbleDuration value="90" />
<RumbleIntensity value="0.100000" />
<RumbleIntensityTrigger value="0.800000" />
<RumbleDamageIntensity value="1.000000" />
<InitialRumbleDurationFps value="150" />
<InitialRumbleIntensityFps value="1.000000" />
<RumbleDurationFps value="95" />
<RumbleIntensityFps value="1.000000" />
<NetworkPlayerDamageModifier value="1.000000" />
<NetworkPedDamageModifier value="1.000000" />
<NetworkHeadShotPlayerDamageModifier value="1.700000" />
<LockOnRange value="65.000000" />
<WeaponRange value="120.000000" />
<BulletDirectionOffsetInDegrees value="0.000000" />
<AiSoundRange value="-1.000000" />
<AiPotentialBlastEventRange value="-1.000000" />
<DamageFallOffRangeMin value="47.500000" />
<DamageFallOffRangeMax value="120.000000" />
<DamageFallOffModifier value="0.300000" />
<VehicleWeaponHash />
<DefaultCameraHash>DEFAULT_THIRD_PERSON_PED_AIM_CAMERA</DefaultCameraHash>
<CoverCameraHash>DEFAULT_THIRD_PERSON_PED_AIM_IN_COVER_CAMERA</CoverCameraHash>
<CoverReadyToFireCameraHash />
<RunAndGunCameraHash>DEFAULT_THIRD_PERSON_PED_RUN_AND_GUN_CAMERA</RunAndGunCameraHash>
<CinematicShootingCameraHash>DEFAULT_THIRD_PERSON_PED_CINEMATIC_SHOOTING_CAMERA</CinematicShootingCameraHash>
<AlternativeOrScopedCameraHash />
<RunAndGunAlternativeOrScopedCameraHash />
<CinematicShootingAlternativeOrScopedCameraHash />
<CameraFov value="35.000000" />
<FirstPersonScopeFov value="20.00000"/>
<FirstPersonScopeAttachmentFov value="20.00000"/>
<FirstPersonRNGOffset x="0.000000" y="0.000000" z="0.000000" />
<FirstPersonRNGRotationOffset x="0.000000" y="0.000000" z="0.000000" />
<FirstPersonLTOffset x="0.000000" y="0.000000" z="0.000000" />
<FirstPersonLTRotationOffset x="0.000000" y="0.000000" z="0.000000" />
<FirstPersonScopeOffset x="0.00000" y="-0.0200" z="-0.0230" />
<FirstPersonScopeAttachmentOffset x="0.00000" y="0.0000" z="-0.0280" />
<FirstPersonScopeRotationOffset x="-0.70000" y="0.0000" z="0.0000" />
<FirstPersonScopeAttachmentRotationOffset x="0.00000" y="0.0000" z="0.0000" />
<FirstPersonAsThirdPersonIdleOffset x="-0.07500000" y="0.000000" z="-0.05" />
<FirstPersonAsThirdPersonRNGOffset x="-0.025000" y="0.000000" z="-0.075000" />
<FirstPersonAsThirdPersonLTOffset x="0.025000" y="0.000000" z="-0.0750000" />
<FirstPersonAsThirdPersonScopeOffset x="0.075000" y="-0.050000" z="-0.060000" />
<FirstPersonAsThirdPersonWeaponBlockedOffset x="-0.1000000" y="0.000000" z="-0.100000" />
<FirstPersonDofSubjectMagnificationPowerFactorNear value="1.025000" />
<FirstPersonDofMaxNearInFocusDistance value="0.000000" />
<FirstPersonDofMaxNearInFocusDistanceBlendLevel value="0.300000" />
<ZoomFactorForAccurateMode value="1.300000" />
<RecoilShakeHash>ASSAULT_RIFLE_RECOIL_SHAKE</RecoilShakeHash>
<RecoilShakeHashFirstPerson>FPS_ASSAULT_RIFLE_RECOIL_SHAKE</RecoilShakeHashFirstPerson>
<AccuracyOffsetShakeHash>DEFAULT_THIRD_PERSON_ACCURACY_OFFSET_SHAKE</AccuracyOffsetShakeHash>
<MinTimeBetweenRecoilShakes value="100" />
<RecoilShakeAmplitude value="0.333000" />
<ExplosionShakeAmplitude value="-1.000000" />
<ReticuleHudPosition x="0.000000" y="0.000000" />
<AimOffsetMin x="0.250000" y="0.200000" z="0.600000" />
<AimProbeLengthMin value="0.430000" />
<AimOffsetMax x="0.165000" y="-0.180000" z="0.470000" />
<AimProbeLengthMax value="0.340000" />
<AimOffsetMinFPSIdle x="0.162000" y="0.225000" z="0.052000" />
<AimOffsetMedFPSIdle x="0.187000" y="0.197000" z="0.321000" />
<AimOffsetMaxFPSIdle x="0.155000" y="0.038000" z="0.364000" />
<AimOffsetEndPosMinFPSIdle x="-0.284000" y="0.612000" z="-0.205000" />
<AimOffsetEndPosMedFPSIdle x="-0.178000" y="0.639000" z="0.616000" />
<AimOffsetEndPosMaxFPSIdle x="-0.21700" y="-0.096000" z="0.887000" />
<AimOffsetMinFPSLT x="0.180000" y="0.231000" z="0.669000" />
<AimOffsetMaxFPSLT x="0.048000" y="-0.225000" z="0.409000" />
<AimOffsetMinFPSRNG x="0.120000" y="0.275000" z="0.509000" />
<AimOffsetMaxFPSRNG x="0.138000" y="-0.212000" z="0.518000" />
<AimOffsetMinFPSScope x="0.090000" y="0.078000" z="0.531000" />
<AimOffsetMaxFPSScope x="0.006000" y="-0.059000" z="0.694000" />
<TorsoAimOffset x="-1.000000" y="0.550000" />
<TorsoCrouchedAimOffset x="0.100000" y="0.120000" />
<LeftHandIkOffset x="0.230000" y="-0.001000" z="-0.052000" />
<ReticuleMinSizeStanding value="0.600000" />
<ReticuleMinSizeCrouched value="0.500000" />
<ReticuleScale value="0.300000" />
<ReticuleStyleHash>WEAPONTYPE_RIFLE</ReticuleStyleHash>
<FirstPersonReticuleStyleHash />
<PickupHash>PICKUP_WEAPON_SCICARBINE</PickupHash>
<MPPickupHash>PICKUP_AMMO_BULLET_MP</MPPickupHash>
<HumanNameHash>WT_RIFLE_CBN</HumanNameHash>
<MovementModeConditionalIdle>MMI_2Handed</MovementModeConditionalIdle>
<StatName>CRBNRIFLE</StatName>
<KnockdownCount value="-1" />
<KillshotImpulseScale value="1.000000" />
<NmShotTuningSet>Automatic</NmShotTuningSet>
<AttachPoints>
<Item>
<AttachBone>WAPClip</AttachBone>
<Components>
<Item>
<Name>COMPONENT_SCICARBINE_CLIP_01</Name>
<Default value="true" />
</Item>
</Components>
</Item>
</AttachPoints>
<GunFeedBone />
<TargetSequenceGroup />
<WeaponFlags>CarriedInHand Automatic Gun CanLockonOnFoot CanLockonInVehicle CanFreeAim TwoHanded AnimReload AnimCrouchFire UsableOnFoot UsableInCover AllowEarlyExitFromFireAnimAfterBulletFired NoLeftHandIKWhenBlocked AllowCloseQuarterKills HasLowCoverReloads HasLowCoverSwaps LongWeapon UseFPSAimIK UseFPSSecondaryMotion</WeaponFlags>
<TintSpecValues ref="TINT_DEFAULT" />
<FiringPatternAliases ref="FIRING_PATTERN_RIFLE" />
<ReloadUpperBodyFixupExpressionData ref="default" />
<AmmoDiminishingRate value="3" />
<AimingBreathingAdditiveWeight value="1.000000" />
<FiringBreathingAdditiveWeight value="1.000000" />
<StealthAimingBreathingAdditiveWeight value="1.000000" />
<StealthFiringBreathingAdditiveWeight value="1.000000" />
<AimingLeanAdditiveWeight value="1.000000" />
<FiringLeanAdditiveWeight value="1.000000" />
<StealthAimingLeanAdditiveWeight value="1.000000" />
<StealthFiringLeanAdditiveWeight value="1.000000" />
<ExpandPedCapsuleRadius value="0.000000" />
<AudioCollisionHash />
<HudDamage value="32" />
<HudSpeed value="65" />
<HudCapacity value="40" />
<HudAccuracy value="55" />
<HudRange value="45" />
</Item>
</Infos>
</Item>
</Infos>
</CWeaponInfoBlob>
请注意,<Item type="CWeaponInfo">
的{{1}}尚未删除,因为它有一个包含单词SCICARBINE的节点,所以它和它的兄弟姐妹一起保存。
答案 0 :(得分:1)
将xml linq用于第一个请求
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
List<XElement> removeNodes = doc.Descendants("WeaponSlots").Descendants("Item").Where(x => !x.Descendants("Entry").Where(y => (string)y == "SLOT_STUNGUN").Any()).ToList();
foreach (XElement removeNode in removeNodes)
{
removeNode.Remove();
}
}
}
}
第二次请求
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
const string ADD_FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XDocument addDoc = XDocument.Load(ADD_FILENAME);
XElement docRoot = doc.Root;
XElement addRoot = addDoc.Root;
foreach (XElement child in addRoot.Elements())
{
string elementName = child.Name.LocalName;
XElement docElement = docRoot.Element(elementName);
docElement.Add(child.FirstNode);
}
}
}
}
答案 1 :(得分:1)
根据jdweng的回答,这就是我想出来的。再次感谢,伙计们!
using System;
using System.Linq;
using System.Xml.Linq;
namespace WeaponInfoTemplateGenerator
{
class Program
{
static void Main(string[] args)
{
if (args.Length < 0)
return;
if (!args.All(i => i.EndsWith(".meta")) && !args.All(i => i.EndsWith(".xml")))
return;
try
{
for (int i = 0; i < args.Length; i++)
{
var arg = args[i];
Console.WriteLine("Enter a string value:");
var userInput = Console.ReadLine();
XDocument doc = XDocument.Load(arg);
doc.RemoveSimilarNodes(userInput, "Entry", "SlotNavigateOrder", "Item", "WeaponSlots", "Item");
doc.RemoveSimilarNodes(userInput, "Entry", "SlotBestOrder", "WeaponSlots", "Item");
doc.ClearNode("TintSpecValues");
doc.ClearNode("FiringPatternAliases");
doc.ClearNode("UpperBodyFixupExpressionData");
doc.ClearNode("AimingInfos");
doc.RemoveSimilarNodes(userInput, "Name", "Infos", "Item", "Infos", "Item");
doc.ClearNode("VehicleWeaponInfos");
doc.Save(arg + ".new.xml");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
Console.ReadLine();
}
Console.WriteLine("Press [Enter] to exit...");
Console.ReadLine();
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace WeaponInfoTemplateGenerator
{
public static class Util
{
public static void RemoveSimilarNodes(this XDocument doc, string targetStringValue, string targetDescendant, params string[] path)
{
// Go to the last node.
IEnumerable<XElement> currentNode = null;
for (int i = 0; i < path.Length; i++)
{
string name = path[i];
if (currentNode == null)
{
currentNode = doc.Descendants(name);
continue;
}
currentNode = currentNode.Descendants(name);
}
// Check the target descendant, and get it's children.
List<XElement> navOrders = currentNode.Where(x => !x.Descendants(targetDescendant).Where(y => ((string)y).Contains(targetStringValue)).Any()).ToList();
// Remove the nodes.
foreach (XElement node in navOrders)
{
node.Remove();
}
}
public static void ClearNode(this XDocument doc, string descendant)
{
List<XElement> desc = doc.Descendants(descendant).ToList();
desc.DescendantNodes().Remove();
}
}
}