根据条件循环两个XElements

时间:2022-11-25 05:33:13

I want to loop an XML tree and test two conditions and found some issues.

我想循环XML树并测试两个条件并发现一些问题。

  1. I can't compare a XElement like an Integer. I've read some other posts (besides this examples) and so far I couldn't figure it out. :S
  2. 我无法像整数那样比较XElement。我已经阅读了其他一些帖子(除了这个例子),到目前为止我无法弄明白。 :S

Link_1

Link_2

  1. In the foreach loop I'm only able to change the first matching element and I would like to do it for all matching XElements. I have tried Any() and All() but wasn't successful.
  2. 在foreach循环中,我只能更改第一个匹配元素,我想为所有匹配的XElements做。我尝试了Any()和All(),但没有成功。

My XML files: (for protein)

我的XML文件:(对于蛋白质)

<?xml version="1.0" encoding="utf-8"?>
<ProteinStructure>
  <SecondaryStructure>
    <StName>HELX_P1</StName>
    <StType>alphaHelix</StType>
    <AmAcidStart>1</AmAcidStart>
    <AmAcidEnd>2</AmAcidEnd>
  </SecondaryStructure>
  <SecondaryStructure>
    <StName>HELX_P2</StName>
    <StType>alphaHelix</StType>
    <AmAcidStart>43</AmAcidStart>
    <AmAcidEnd>53</AmAcidEnd>
  </SecondaryStructure>

My XML files: (for atom)

我的XML文件:(对于atom)

<?xml version="1.0" encoding="utf-8"?>
<Molecule>
  <Atom>
    <AtNum>1</AtNum>
    <AmAcSeq>2</AmAcSeq>
    <AtType>N</AtType>
    <StType>turn</StType>
  </Atom>
  <Atom>
    <AtNum>2</AtNum>
    <AmAcSeq>2</AmAcSeq>
    <AtType>CA</AtType>
    <StType>turn</StType>
  </Atom>
  <Atom>
    <AtNum>2</AtNum>
    <AmAcSeq>2</AmAcSeq>
    <AtType>C</AtType>
    <StType>turn</StType>
  </Atom>
  <Atom>
    <AtNum>1</AtNum>
    <AmAcSeq>3</AmAcSeq>
    <AtType>N</AtType>
    <StType>turn</StType>
  </Atom>

My code so far:

我的代码到目前为止:

			XDocument atom = XDocument.Load (@"C:\Users\RuiGarcia\Documents\MIB\INESC\C#Tutorial\ProjectC#\Molecule_00\PDBLibary_00\Data\__3Q26.xml");
			XDocument protein = XDocument.Load (@"C:\Users\RuiGarcia\Documents\MIB\INESC\C#Tutorial\ProjectC#\Molecule_00\PDBLibary_00\Data\_3Q26.xml");

			//Change secondary structure tag type "turn" to helixAlpha or betaSheet
			foreach (XElement amAc in protein.Descendants ("SecondaryStructure"))
			{
				atom.Element ("Molecule")
					.Elements ("Atom")
					.Where (x => (int?)x.Element("AmAcSeq") >= (int?)amAc.Element("AmAcidStart") && x => (int?)ToInt16.x.Element ("AmAcSeq") <= (int?)amAc.Element("AmAcidEnd"))
					.Select (x => x.Element("StType")).FirstOrDefault().SetValue(amAc.Element("StType"));
//				Console.WriteLine (amAc.Element("AmAcidStart").Value);
//					.Where (x => Convert.ToInt16(x.Element("AmAcSeq").Value) <= Convert.ToInt16(amAc.Element("AmAcidStart").Value) && x => Convert.ToInt16(x.Element ("AmAcSeq").Value) >= Convert.ToInt16(amAc.Element("AmAcidStart")))
//					.Where (x => (int?)x.Element("AmAcSeq") >= (int?)amAc.Element("AmAcidStart") && x => (int?)ToInt16.x.Element ("AmAcSeq") <= (int?)amAc.Element("AmAcidStart"))
			}

			atom.Save(@"C:\Users\RuiGarcia\Documents\MIB\INESC\C#Tutorial\ProjectC#\Molecule_00\PDBLibary_00\Data\__3Q26.xml");

P.S. - How can I format correctly the code without separating it in the code sample?

附: - 如何在不将代码示例中的代码分开的情况下正确格式化代码?

Thanks in advance.

提前致谢。

2 个解决方案

#1


0  

You need a second foreach to iterate through the results. I lifted some values and included an example below of doing that.

您需要第二个foreach来遍历结果。我提出了一些价值观,并在下面举了一个例子。

XDocument atom = XDocument.Load (@"...\__3Q26.xml");
XDocument protein = XDocument.Load (@"...\_3Q26.xml");

//Change secondary structure tag type "turn" to helixAlpha or betaSheet
foreach (XElement amAc in protein.Descendants ("SecondaryStructure"))
{
    int? start = (int?)amAc.Element("AmAcidStart");
    int? end = (int?)amAc.Element("AmAcidEnd");
    string stType = (string)amAc.Element("StType");

    IEnumerable<XElement> atoms = atom.Element("Molecule").Elements("Atom");

    // Here we are iterating again in each matching result
    foreach (XElement atomElement in atoms.Where(elem => (int?)elem.Element("AmAcSeq") >= start && (int?)elem.Element("AmAcSeq") <= end))
    {
        atomElement.SetValue(stType);
    }
}

#2


0  

I see a couple problems here:

我在这看到几个问题:

  1. You need to use nested foreach loops rather than a FirstOrDefault().
  2. 您需要使用嵌套的foreach循环而不是FirstOrDefault()。

  3. Your condition (int?)ToInt16.x.Element ("AmAcSeq") <= (int?)amAc.Element("AmAcidStart") doesn't even compile, and should almost certainly be something like (int?)x.Element ("AmAcSeq") <= (int?)amAc.Element("AmAcidEnd"))
  4. 你的条件(int?)ToInt16.x.Element(“AmAcSeq”)<=(int?)amAc.Element(“AmAcidStart”)甚至不编译,几乎可以肯定是(int?)x.Element (“AmAcSeq”)<=(int?)amAc.Element(“AmAcidEnd”))

Thus:

        foreach (XElement secondaryStructure in protein.Descendants ("SecondaryStructure"))
        {
            foreach (var atomStType in atom.Element ("Molecule")
                .Elements ("Atom")
                .Where(a => (int?)a.Element("AmAcSeq") >= (int?)secondaryStructure.Element("AmAcidStart") && (int?)a.Element("AmAcSeq") <= (int?)secondaryStructure.Element("AmAcidEnd"))
                .Select (a => a.Element("StType")))
            {
                atomStType.SetValue((string)secondaryStructure.Element("StType"));
            }
        }

#1


0  

You need a second foreach to iterate through the results. I lifted some values and included an example below of doing that.

您需要第二个foreach来遍历结果。我提出了一些价值观,并在下面举了一个例子。

XDocument atom = XDocument.Load (@"...\__3Q26.xml");
XDocument protein = XDocument.Load (@"...\_3Q26.xml");

//Change secondary structure tag type "turn" to helixAlpha or betaSheet
foreach (XElement amAc in protein.Descendants ("SecondaryStructure"))
{
    int? start = (int?)amAc.Element("AmAcidStart");
    int? end = (int?)amAc.Element("AmAcidEnd");
    string stType = (string)amAc.Element("StType");

    IEnumerable<XElement> atoms = atom.Element("Molecule").Elements("Atom");

    // Here we are iterating again in each matching result
    foreach (XElement atomElement in atoms.Where(elem => (int?)elem.Element("AmAcSeq") >= start && (int?)elem.Element("AmAcSeq") <= end))
    {
        atomElement.SetValue(stType);
    }
}

#2


0  

I see a couple problems here:

我在这看到几个问题:

  1. You need to use nested foreach loops rather than a FirstOrDefault().
  2. 您需要使用嵌套的foreach循环而不是FirstOrDefault()。

  3. Your condition (int?)ToInt16.x.Element ("AmAcSeq") <= (int?)amAc.Element("AmAcidStart") doesn't even compile, and should almost certainly be something like (int?)x.Element ("AmAcSeq") <= (int?)amAc.Element("AmAcidEnd"))
  4. 你的条件(int?)ToInt16.x.Element(“AmAcSeq”)<=(int?)amAc.Element(“AmAcidStart”)甚至不编译,几乎可以肯定是(int?)x.Element (“AmAcSeq”)<=(int?)amAc.Element(“AmAcidEnd”))

Thus:

        foreach (XElement secondaryStructure in protein.Descendants ("SecondaryStructure"))
        {
            foreach (var atomStType in atom.Element ("Molecule")
                .Elements ("Atom")
                .Where(a => (int?)a.Element("AmAcSeq") >= (int?)secondaryStructure.Element("AmAcidStart") && (int?)a.Element("AmAcSeq") <= (int?)secondaryStructure.Element("AmAcidEnd"))
                .Select (a => a.Element("StType")))
            {
                atomStType.SetValue((string)secondaryStructure.Element("StType"));
            }
        }