【发布时间】:2017-05-27 20:36:48
【问题描述】:
我是新来的,如果我做错了,请原谅。
我有一系列具有不同 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”,并让程序删除任何不包含该单词的“项目”节点。
我已经成功地完成了这件事,但不是我想要的那样。我有一个包含 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>
请注意,SCICARBINE 的 <Item type="CWeaponInfo"> 尚未删除,因为它有一个节点包含 SCICARBINE 一词,因此它和它的兄弟姐妹都保留了下来。
【问题讨论】:
-
你考虑过使用 Linq to XML 吗? docs.microsoft.com/en-us/dotnet/csharp/programming-guide/… 这将允许您将 XML 文档视为另一个 IEnumerable 并针对它编写简单的查询。现在无法编写示例,因为我不在电脑旁。
-
嗯,所以用Linq重新构造xml?听起来很有趣,我将不得不做更多的研究。当您有机会时,将不胜感激一个不错的代码示例!谢谢! :)
标签: c# xml console-application