كيف يمكنني حذف عقدة معينة داخل ملف XML باستخدام vbscript

StackOverflow https://stackoverflow.com/questions/173706

  •  05-07-2019
  •  | 
  •  

سؤال

أواجه مشكلة تتمثل في عدم قدرتي على تحديد عقدة XML محددة يجب حذفها.لقد حاولت بالفعل تحديد العقدة باستخدام XPath الذي يعمل بشكل جيد مع بعض ملفات XML ولكن لا يمكنني معرفة XPath الصحيح لعقدة في ملف أكثر تعقيدًا.

هل يعرف أي شخص أداة مجانية يمكنها تحميل ملف XML بحيث يمكن للمستخدم تحديد عقدة معينة واستلام XPath الدقيق دون الحاجة إلى تعداد في المسار؟

/root/anything[2] <-- لسوء الحظ لا أستطيع استخدام مثل هذا البيان لأن رقم العنصر قد يتغير.أحتاج إلى تعبير يعتمد على سمة.

في حالة عدم وجود أداة مجانية لهذه العملية، هل يعرف أحد طريقة أخرى كيف يمكنني تحديد العقدة المطلوبة؟

نموذج XML:

عقدة الجذر: smsFormData

صفات: xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd = "http://www.w3.org/2001/XMLSchema" FormatVersion = "1.0" xmlns = "http: //schemas.microsoft.com/SystemsManagementServer/2005/03/ConsoleFramework"

العقدة التابعة: استمارة

صفات: المعرف = "بعض GUID" CustomData = "بعض البيانات" FormType = "بعض النوع" ForceRefresh = "خطأ"

عقدة الطفل/الطفل: الصفحات

عقدة الطفل/الطفل/الطفل: صفحة

صفات: معرف البائع = "اسم البائع" معرف = "بعض GUID" التجميع = "اسم ملف dll" مساحة الاسم = "بعض مساحة الاسم" النوع = "بعض النوع" معرف المساعدة = "">

سيكون تعبير xPath الخاص بي لتحديد هذه الصفحة المحددة الآن:

xPath = /SmsFormData/Form/Pages/Page[@Id="some Guid"]

للقيام بالاختيار أستخدم كود vbscript التالي:

Set objDOM = CreateObject("Msxml2.DOMDocument.4.0") 
objDOM.async = false            
objDOM.load(file)       
set objNode = objDOM.selectSingleNode(xPath)

المشكلة الآن هي أن objNode الكائن فارغ.لم يتم تحديد العقدة، ولكن لماذا؟

هل كانت مفيدة؟

المحلول

هذه مشكلة مساحة الاسم الافتراضية.حاول تضمين التعليمة البرمجية التالية بعد التحميل في ملف XML:

objDom.SetProperty "SelectionNamespaces", "xmlns:cf=""http://schemas.microsoft.com/SystemsManagementServer/2005/03/ConsoleFramework"""

ثم يمكنك استخدام هذا cf البادئة في XPath الخاص بك على سبيل المثال:

objDom.SelectSingleNode("/cf:SmsFormData/cf:Form/cf:Pages/cf:Page[@Id='Some Guid']")

في حين أن هذا قد يبدو غريبا بعض الشيء، إلا أنه سلوك مقصود.نلقي نظرة على http://support.microsoft.com/kb/288147 لمزيد من المعلومات، وقد تجد http://msdn.microsoft.com/en-us/library/ms950779.aspx مفيدة كذلك.

نصائح أخرى

شكرا لردك السريع!هذا يعمل بالتأكيد في الحالات البسيطة ولكن هذا لا يعمل في حالتي المحددة :(

لذلك دعونا ندخل في التفاصيل:

عقدة الجذر: smsFormData

صفات: xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd = "http://www.w3.org/2001/XMLSchema" FormatVersion = "1.0" xmlns = "http: //schemas.microsoft.com/SystemsManagementServer/2005/03/ConsoleFramework"

العقدة التابعة: استمارة

صفات: المعرف = "بعض GUID" CustomData = "بعض البيانات" FormType = "بعض النوع" ForceRefresh = "خطأ"

عقدة الطفل/الطفل:الصفحات

عقدة الطفل/الطفل/الطفل: صفحة

صفات: معرف البائع = "اسم البائع" معرف = "بعض GUID" التجميع = "اسم ملف dll" مساحة الاسم = "بعض مساحة الاسم" النوع = "بعض النوع" معرف المساعدة = "">

سيكون تعبير xPath الخاص بي لتحديد هذه الصفحة المحددة الآن:

xPath = "/SmsFormData/Form/Pages/Page[@Id="some Guid"]"

للقيام بالاختيار أستخدم كود vbscript التالي:

Set objDOM = CreateObject("Msxml2.DOMDocument.4.0") 

objDOM.async = false        
objDOM.load(file)       

set objNode = objDOM.selectSingleNode(xPath) 

المشكلة الآن هي أن كائن objNode فارغ.لم يتم تحديد العقدة، ولكن لماذا؟

أوه، وبالمناسبة:شكرًا على نصيحة Visual XPath!لقد حاولت استخدامه ولكن لسوء الحظ فإنه يعمل بطريقة التعداد :/

تحتاج إلى ضبط لغة التحديد على XPath باستخدام

objDOM.SetProperty "SelectionLanguage"، "XPath"

بمجرد تعيين هذه الخاصية، يمكنك بعد ذلك استخدام XPath الكامل للوصول إلى أي عناصر تريدها

إذا كان لديك متصفح Firefox، فيمكنك ببساطة تثبيت DOM Inspector (مطلوب فقط لـ Firefox 3.0)، وملحقات XPather.بعد ذلك، يمكنك الانتقال إلى العقدة التي تريدها في نافذة DOM Inspector، وسيتم عرض XPath المقابل في شريط أدوات XPather في نفس النافذة.

مفتش DOM: https://addons.mozilla.org/en-US/firefox/addon/6622

XPather: https://addons.mozilla.org/en-US/firefox/addon/1192?id=1192

يبدو أن XPather يستخدم السمات (وليس التعداد) كلما أمكن ذلك لتحديد العقد (على الأقل هذا ما وجدته في تجربتي الصغيرة...).امل ان يساعد...

بالنظر إلى ملف XML التالي:

<root>
  <anything foo="bar">value1</anything>
  <anything foo="qux">value2</anything>
</root>

...يمكنك الحصول على قيمة عقدة أي شيء الثانية باستخدام تعبير XPath:

/root/anything[@foo="qux"]

(لذلك، بدلاً من الفهرس المرقّم، يمكنك استخدام @property="value" كمحدد).

أما بالنسبة لأداة لإنشاء استعلامات مثل هذه تلقائيًا، فإن الاسم المناسب لها هو مسار XPath المرئي يجب أن تقوم بالخدعة، وهي مجانية (حتى أنها تأتي مع كود مصدر C#).

التعديل بعد المتابعة بالملصق:يعمل هذا النوع من تحديد XPath أيضًا مع "الحالات البسيطة" كما هو الحال مع المستندات الأكثر تعقيدًا.أنت يفعل عليك التأكد من صحة تعبير XPath، بالطبع، وعلى الرغم من أن Visual XPath سيستخدم بالفعل فهارس رقمية، إلا أنه على الأقل يوفر لك بقية التعبير، ويمكنك بسهولة استبدال محدد @property="value" للرقم ، واختبار النتيجة.

بالنظر إلى مثال XML أعلاه، فإن VBscript هذا:

objDOM.selectSingleNode("/root/anything[@foo=""qux""]/text()").nodeValue

...إرجاع السلسلة "value2":اعتمادًا على احتياجاتك، قد تحتاج إلى تعديل الأشياء قليلًا (مرة أخرى، أدوات مثل Visual XPath، أو أي أداة جيدة مرجع XPath سوف تساعدك على ذلك).

حسنًا،...لدي انطباع بأن المشكلة يجب أن تكون مستندة إلى الملف.حتى لو قمت بتعيين الخاصية لـ SelectionLanguage وإذا استخدمت XPath المُعدَّد (الذي حصلت عليه باستخدام FireFox XPather)، فسيظل كائن العقدة فارغًا.

هل لدى أي شخص فكرة عما يمكن أن يكون الخطأ؟يأتي ملف xml مع تطبيق Microsoft وبالتالي يجب أن يكون صالحًا.على الأقل ليس لدي أي مشاكل أثناء فتح الملف أو استخدامه داخل التطبيق لذا يجب أن يكون بناء الجملة على ما يرام.

أو ربما يكون لدى شخص ما وظيفة vbscript التي تتكرر خلال ملف xml بالكامل للعثور على العقدة المطلوبة لحذفها؟

مشكلتك هي أن لديك مساحة اسم افتراضية.مساحة الاسم الافتراضية لـ XPath هي دائمًا مساحة الاسم "بدون اسم".

انت تحتاج:-

sNamespaces = "xmlns:cf='http://schemas.microsoft.com/SystemsManagementServer/2005/03/ConsoleFramework'"
objDOM.setProperty "SelectionNamespaces", sNamespaces

الآن يمكنك استخدام XPath الخاص بك: -

xPath = "/cf:SmsFormData/cf:Form/cf:Pages/cf:Page[@Id=""some Guid""]"

لست متأكدًا مما إذا كان ذلك مفيدًا لك، ولكن واجهت مشكلة مماثلة.

كان لدي ملف XML تم إنشاؤه بواسطة التطبيق وأحتاج إلى إدارته.وكانت على الشكل:<LoginData> <GeneralData> <LoginMask>65537</LoginMask> </GeneralData> <UserData> <User> <Username>TEST0</Username> ... </User> <User> <Username>TEST1</Username> ... </User> </UserData> </LoginData>

كنت بحاجة لمطابقة اسم المستخدم وإزالة علامات المستخدم الأخرى.

لقد استغرق مني الأمر (لكوني مبتدئًا كاملاً في XML) وقتًا طويلاً لحل هذه المشكلة، ولكن في النهاية قمت بالنقر على المطابقة على العقدة، وحذف العقدة الفرعية للعقدة الأصلية:

for each x in oXmlDoc.documentElement.selectSingleNode("UserData").childNodes if x.getElementsByTagName("Username").item(0).text = "TEST1" then set exx = x.getElementsByTagName("Username").item(0) wscript.echo(x.getElementsByTagName("Username").item(0).text) wScript.echo(x.nodename & ": " & x.text) x.parentNode.removeChild(x) end if next

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top