How to Parse Xml and Get Instances of a Particular Node Attribute

How to parse XML and get instances of a particular node attribute?

I suggest ElementTree. There are other compatible implementations of the same API, such as lxml, and cElementTree in the Python standard library itself; but, in this context, what they chiefly add is even more speed -- the ease of programming part depends on the API, which ElementTree defines.

First build an Element instance root from the XML, e.g. with the XML function, or by parsing a file with something like:

import xml.etree.ElementTree as ET
root = ET.parse('thefile.xml').getroot()

Or any of the many other ways shown at ElementTree. Then do something like:

for type_tag in root.findall('bar/type'):
value = type_tag.get('foobar')
print(value)

Output:

1
2

C# Parse XML & action if attribute of node matches a string

You misunderstood the attribute ToString() function. The way you do it you are comparing the string of the class name "System.Xml.XmlAttribute" instead of the actual value you wanted. So assuming all of your other code works this should work

    foreach (XmlNode node in ParseExistingKingdomXML_xDoc.DocumentElement)
{
if (node.Name == "Kingdom")
{
var attribute = node.Attributes["title"].Value;
if (attribute == XMLExistingKingdomsStrings.KingdomName) {
XMLExistingKingdomsStrings.KingdomID = node.Attributes["title"].Value;
}
}
}

How to search for a Xml node with a given attribute value in python

xml.etree.ElementTree provides only limited support for XPath expressions for locating elements in a tree, and that doesn't include xpath contains() function. See the documentation for list of supported xpath syntax.

You need to resort to a library that provide better xpath support, like lxml, or use simpler xpath and do further filtering manually, for example :

import xml.etree.ElementTree as ET
tree = ET.parse('test.xml')
root = tree.getroot()
list = filter(lambda x: 'Pana' in x.get('name'), root.findall(".//country[@name]"))

Parse XML based on node attribute and edit when found

Here's a suggested approach using a scripting dictionary to track what sections have already been added, so we can easily get a reference to the required element to which the description needs to be added/appended.

Option Explicit

Sub RPCTranslatesCombinedInfoBackwardsChecking()

Const THE_NS As String = "urn:Riwo.Pcs.Localization"

Dim oXMLDoc As Object, oRoot As Object, dict As Object, sSectionPrefix As String
Dim sSectionName As String, sDescription As String, txt, oPI As Object, lRow As Long
Dim oElmSection As Object, dictKey As String, oElmTranslation As Object

Set dict = CreateObject("scripting.dictionary")
Set oXMLDoc = CreateObject("MSXML2.DOMDocument")
Set oPI = oXMLDoc.createProcessingInstruction("xml", "version=""1.0"" encoding=""UTF-8""")

'create the root element
Set oRoot = CreateWithAttributes(oXMLDoc, "Translations", THE_NS, "", _
Array("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance", _
"xmlns:xsd", "http://www.w3.org/2001/XMLSchema", _
"code", "nl", _
"description", "Dutch")) '

oXMLDoc.appendchild oRoot

lRow = 2

With ActiveSheet
Do While .Cells(lRow, 4).Value <> ""

sSectionPrefix = Right(.Cells(lRow, 1).Value, Len(.Cells(lRow, 1).Value) - 1)
sSectionName = .Cells(lRow, 4).Value
dictKey = sSectionPrefix & "." & sSectionName

'first time seeing this section name? - add to document and to dictionary
If Not dict.exists(dictKey) Then
Set oElmSection = CreateWithAttributes(oXMLDoc, "Section", THE_NS, "", _
Array("name", dictKey))
oRoot.appendchild oElmSection

Set oElmTranslation = CreateWithAttributes(oXMLDoc, "Translation", THE_NS, "", _
Array("key", "Info"))
oElmSection.appendchild oElmTranslation
Set dict(dictKey) = oElmTranslation 'store reference in dictionary
End If

Set oElmTranslation = dict(dictKey) 'get the node to add content

sDescription = .Cells(lRow, 1).Value & " " & .Cells(lRow, 2).Value & " " & _
.Cells(lRow, 3).Value & " " & .Cells(lRow, 5).Value


txt = oElmTranslation.Text

If Len(txt) > 0 Then txt = txt & "[br]"
txt = txt & sDescription

oElmTranslation.NodetypedValue = txt

lRow = lRow + 1
Loop
End With

Debug.Print oXMLDoc.XML
oXMLDoc.Save "C:\Users\thomas.RIWO\Desktop\Translations\RPC test\test2.xml"

End Sub

Having previously done a bunch of XML creation, I find it's much easier to see what you're doing if you factor out the repetitive parts into a separate utility method such as the one shown below. It's quite basic, but covers a lot of what you need to do while constructing an XML document.

'Utility method: create and return an element, with 
' optional namespace, value and attributes
Function CreateWithAttributes(doc As Object, elName As String, _
elNameSpace As String, elValue As String, Optional attr As Variant = Empty)
Dim el, u, i As Long, att As Object, txt As Object
'create the node
Set el = doc.CreateNode(1, elName, elNameSpace)
'if have attributes, loop and add
If Not IsEmpty(attr) Then
For i = 0 To UBound(attr) Step 2
Set att = doc.CreateAttribute(attr(i))
att.Value = attr(i + 1)
el.Attributes.setNamedItem att
Next i
End If
'any element content to add?
If Len(elValue) > 0 Then
Set txt = doc.createTextNode(elValue)
el.appendchild txt
End If
Set CreateWithAttributes = el
End Function

Parse XML with Attributes

As the error tells you, you haven't defined the singleton, which defines what numbered node the value is from. Most likely you just want the 1st node. I also changed your data types, as I doubt your values could all be up to 1 billion characters long (though I use an nvarchar(2) for most, which may not be long enough in all places).

This gives something like the following:

DECLARE @XML xml = '<someStructure>
<Tag1 Qualifier = "QQ" Name = "Name">
<Tag2 Code = "CD" Name = "SomeName">
<Tag3 Qualifier = "QW" Number = "22"/>
</Tag2>
</Tag1>
<Tag1 Qualifier = "NN" Name = ""/>
<Tag1 Qualifier = "QE" Name = "Name2">
<Tag2 Code = "CD" Name = "SomeName2">
<Tag3 Qualifier = "QW" Number = "22"/>
</Tag2>
</Tag1>
</someStructure>';

SELECT sS.T1.value('(@Qualifier)[1]','nvarchar(2)') AS Tag1Qualifier, --Does this "need" to be up to 1 billion characters long?
sS.T1.value('(@Name)[1]','nvarchar(20)') AS Tag1Name, --Does this "need" to be up to 1 billion characters long?
sS.T1.value('(Tag2/@Code)[1]','nvarchar(2)') AS Tag2Code, --Does this "need" to be up to 1 billion characters long?
sS.T1.value('(Tag2/@Name)[1]','nvarchar(20)') AS Tag2Name, --Does this "need" to be up to 1 billion characters long?
sS.T1.value('(Tag2/Tag3/@Qualifier)[1]','nvarchar(2)') AS Tag3Qualifier, --Does this "need" to be up to 1 billion characters long?
sS.T1.value('(Tag2/Tag3/@Number)[1]','int') AS Tag3Number --Does this "need" to be up to 1 billion characters long?
FROM (VALUES(@XML))V(X)
CROSS APPLY V.X.nodes('/someStructure/Tag1') sS(T1);

How to parse an XML element that has an attribute inside it? Asp.net C#

Use XDocument instead of XmlReader much easier to query.

first example

some code where you have too loop thru the results that did return from the LINQ query. But since you only have one < time > element and one < temperature > element inside that you can better use the second example

       // Create XDocument and load in the file
XDocument _doc = XDocument.Load("C:\\t\\My File2.txt");
//select all time element where attribute day.Value == to any day you give it just change "2017-04-18"
var time = _doc.XPathSelectElements("/weatherdata/forecast/time").Where(c => c.Attribute("day").Value == "2017-04-18");
// Get IEnumerable of temperatures in the time element
var temp = time.Select(x => x.Element("temperature"));

// loop temperatures and get the attribute value from the element
foreach (var element in temp)
{
string day = element.Attribute("day").Value;
string min = element.Attribute("min").Value;
string max = element.Attribute("max").Value;
string night = element.Attribute("night").Value;
string eve = element.Attribute("eve").Value;
string morn = element.Attribute("morn").Value;
MessageBox.Show($"day:{day},\nmin:{min},\nmax:{max},\nnight:{night},\neve:{eve},\nmorn:{morn}");
}

Second example

I get the first one of a query result, so you don't have to loop to get one element. It is a bit riskier because you can get a null reference exception when no elements are found. but by a simple if you can catch it before it will be thrown.

         // Create XDocument and load in the file my case it is the path "C:\\t\\My File2.txt"
XDocument _doc = XDocument.Load("C:\\t\\My File2.txt");
// Select all time elements where attribute day.Value == to any day you give it, just change "2017-04-18"
// And select the first one of that result as I aspect there is only one time a day
var time = _doc.XPathSelectElements("/weatherdata/forecast/time").Where(c => c.Attribute("day").Value == "2017-04-18").FirstOrDefault();
// Get the children of time element by using .Elements() and take the first one of that.
// You only have one temperature element in a time element so it will take that one with FirstOrDefault();
var temp = time.Elements().FirstOrDefault();
// assign attributes values to string
string day = temp.Attribute("day").Value;
string min = temp.Attribute("min").Value;
string max = temp.Attribute("max").Value;
string night = temp.Attribute("night").Value;
string eve = temp.Attribute("eve").Value;
string morn = temp.Attribute("morn").Value;

// control
MessageBox.Show($"day:{day},\nmin:{min},\nmax:{max},\nnight:{night},\neve:{eve},\nmorn:{morn}");

Result with day "2017-04-18":

Sample Image

How to parse the attribute value of a specific tag of an xml file which has multiple occurrences through Lua?

LuaXML seems to be pretty minimal and xml.find states:

Returns the first (sub-)table which matches the search condition or
nil.

A simpler solution would be using Lua string pattern:

local file = io.open("oem.xml", "rb")   -- Open file for reading (binary data)
for name, value in file:read("*a"):gmatch("<Attribute name=\"(.-)\" value=\"(.-)\" />") do -- Read whole file content and iterate through attribute matches
print(string.format("Name: %s\nValue: %s", name, value)) -- Print what we got
end
file:close() -- Close file (for instant lock-free, no waiting for garbage collector)

Don't forget to check file for being valid.



Related Topics



Leave a reply



Submit