0

所以我使用 python 来帮助将文本文件更改为 xml。下面的一些文本文件。

:
Breakfast Breads

Gluten Free Nut Loaf
Makes 1 loaf

150 g (51/2 oz./11/2 cups) 
almond meal
30 g (1 oz./1/4 cup)
walnuts, coarsely chopped
1/4 teaspoon 
gluten-free baking powder

我不确定这是否可以复制,因为它可能是文件本身的幽灵。但如果你能尝试那就太好了。

为了解释当前的步骤,我的代码很简陋,寻找冒号,它知道下一行是一般类别,然后切换一个步骤变量。然后下一步将跳过空行 '\r\n' 直到找到一个非空行,该行标识了单个配方的开头及其名称。循环中的下一行,如果为空,则更改步骤,否则为服务大小编写 xml,然后更改步骤。

在这里,我们到达成分步骤。所以奇数行是数量,偶数行是实际成分。

if step == 2:
    if line == empty: 
        continue
    else:
        xmlMenu.write("\n\t<ingredients>") 
        qty = line
        qtyXML = ("\n\t\t<qty>\n\t\t\t" + qty + "\t\t</qty>")
        xmlMenu.write(qtyXML)
        step = 2.2
        continue

if step == 2.2:
        if menu.next() == empty:
            ingredient = line
            pass
            ingredientXML = ("\n\t\t<ingredient>\n\t\t\t" + ingredient + "\t\t</ingredient>\n\t</ingredients>")
            xmlMenu.write(ingredientXML)
            step = 3
            continue

        else:
            ingredient = line
            ingredientXML = ("\n\t\t<ingredient>\n\t\t\t" + ingredient + "\t\t</ingredient>\n\t</ingredients>")
            xmlMenu.write(ingredientXML)
            step = 2
            continue

我的问题,当它达到第二组数量/成分时,它似乎跳过了杏仁粉的数量,因此搞砸了整个 xml 文件。

<recipe>
    <category>
        Breakfast Breads
    </category>
    <name>
        Gluten Free Nut Loaf
    </name>
    <servings>
        Makes 1 loaf
    </servings>
    <ingredients>
        <qty>
            150 g (51/2 oz./11/2 cups) 
        </qty>
        <ingredient>
            almond meal
        </ingredient>
    </ingredients>
    <ingredients>
        <qty>
            walnuts, coarsely chopped
        </qty>
        <ingredient>
            1/4 teaspoon 
        </ingredient>
    </ingredients>

如果我的代码在某处只是废话,有人有什么想法吗?此外,任何有关更好方法的建议。我仍然是初学者级别的编程。

//编辑更多代码。当它开始一个新的配方时,代码在集合结束时仍在工作中。

empty = '\r\n'
colon = ':'
new_contents = []

category = ''
categoryXML = ''

recipe = ''
recipeXML = ''

servings = ''
servingsXML = ''

ingrediants = ''
ingrediantsXML = ''

ingredient = ''
ingredientXML = ''
qty = ''
qtyXML = ''

instructions = ''
instructionsXML = ''

intNo = ''
intNoXML = ''
instruction = ''
instructionXML = ''

step = ''

x = 0

menu = open("menuTextFormat.txt", 'r')
xmlMenu = open('menuTextXML.txt', 'w')

for line in menu:
    # if not line.strip():
    #    continue
    #else:
    #     new_contents.append(line)
    if colon in line:
        step = 0
        continue

    if step == 0: 
        if not line:
            continue 
        else:       
            category = line
            categoryXML = "<recipe>\n\t<category>\n\t\t" + category + "\t</category>"
            xmlMenu.write(categoryXML)    
            step = 1            
            continue

    if step == 1:
        if line == empty:
            continue 
        else:
            recipe = line
            recipeXML = ("\n\t<name>\n\t\t" + recipe + "\t</name>")
            xmlMenu.write(recipeXML)
            step = 12
            continue

    if step == 12:
        if line == empty:
            step = 2
            continue
        else: 
            servings = line
            servingsXML = ("\n\t<servings>\n\t\t" + servings + "\t</servings>")
            xmlMenu.write(servingsXML)
            step = 2

            continue

    if step == 2:
        if line == empty: 
            continue
        else:
            xmlMenu.write("\n\t<ingredients>") 
            qty = line
            qtyXML = ("\n\t\t<qty>\n\t\t\t" + qty + "\t\t</qty>")
            xmlMenu.write(qtyXML)
            step = 22
            continue

    if step == 22:
            if menu.next() == empty:
                ingredient = line
                ingredientXML = ("\n\t\t<ingredient>\n\t\t\t" + ingredient + "\t\t</ingredient>\n\t</ingredients>")
                xmlMenu.write(ingredientXML)
                step = 3
                continue

            else:
                ingredient = line
                ingredientXML = ("\n\t\t<ingredient>\n\t\t\t" + ingredient + "\t\t</ingredient>\n\t</ingredients>")
                xmlMenu.write(ingredientXML)
                step = 2
                continue

    if step == 3:
        if line == empty:
            continue 
        else:
            x += 1
            intNoXML = ("\n\t\t<id>\n\t\t\t" + str(x) + "\n\t\t</id>")
            xmlMenu.write(intNoXML)
            instruction = line
            instructionXML = ("\n\t\t<instruction>\n\t\t\t" + instruction + "\t\t</instruction>")
            xmlMenu.write(instructionXML)
            if menu.next() == empty:
                step = 4
                continue
            else:
                continue
            continue

    if step == 4:
        if not menu.next():
            break
        else:
            step = 1
            continue


    #print line

#xmlMenu.write("".join(new_contents))


xmlMenu.close()
menu.close()


:
Breakfast Breads

Gluten Free Nut Loaf
Makes 1 loaf

150 g (51/2 oz./11/2 cups) 
almond meal
30 g (1 oz./1/4 cup)
walnuts, coarsely chopped
1/4 teaspoon 
gluten-free baking powder
1 teaspoon 
ground cinnamon
95 g (31/4 oz./3/4 cup) 
arrowroot (tapioca) flour
1/2 teaspoon 
sea salt
3 
organic eggs
1/2 teaspoon 
stevia powder
3 tablespoons 
grape seed oil
2 tablespoons 
coconut Milk
1 teaspoon 
apple cider vinegar

Preheat the oven to 180∫C (350∫F/Gas 4). 
Grease a 20 x 9 cm (8 x 31/2 inch) loaf (bar) tin.
Put the almond meal, walnuts, baking powder, cinnamon, arrowroot flour and salt in a large bowl and mix well with a wooden spoon. 
Crack the eggs into a separate bowl and whisk using an electric mixer until pale and fluffy, about 11/2 minutes. 
Add the stevia, grape seed oil, coconut milk and vinegar and mix gently. 
Pour the mixture into the dry ingredients and stir to combine. 
Spoon the mixture into the greased tin and bake for about 40 minutes, or until a skewer inserted in the centre of the loaf comes out clean. 
Remove the bread from the oven and leave to cool in the tin for a few minutes, before turning out onto a wire rack to cool completely. 
Enjoy the bread melt-in-the-mouth warm, or at room temperature with your favourite topping.  

Basic Gluten Free Loaf

2Ω cups 
blanched almond flour
Ω teaspoon 
baking soda
1 tsp. 
bicarbonate of soda
3 
eggs beaten
1 tsp. 
stevia powder
Ω teaspoon 
apple cider vinegar
!!
Pinch sea salt

Preheat oven to 250 degrees Celsius
Grease a small loaf pan
Combine dry ingredients in a bowl
In a separate bowl place eggs and apple cider vinegar
Spoon the mixture into loaf pan
Bake for 50 mins until set
Cool on wire rack
Slice when cool

更多的数据。

4

2 回答 2

2

如果您将代码划分为函数,其中每个函数只负责识别一个小功能,您的代码将更容易理解,例如:

def parse_next_receipe(lines, pos=0):
    while 1:
        if pos >= len(lines):
            break

        line = lines[pos]
        if line.strip() == ':':
            pos, receipe = parse_receipe(lines, pos)
            yield receipe  # or write it directly to the xml file...
        else:
            pos += 1

def parse_receipe(lines, pos):
    pos, name = parse_name(lines, pos)
    pos, description = parse_description(lines, pos)
    ingredients = []

    while 1:
        pos, ingredient = parse_ingredient(lines, pos)
        if pos == -1:
            break
        else:
            ingredients.append(ingredient)

    return (name, description, ingredients)


def parse_name(lines, pos): ...

def parse_description(lines, pos): ...

def parse_ingredient(lines, pos):
    try:
        pos, quantity = parse_quantity(lines, pos)
        pos, ingredient = parse_ingredientname(lines, pos)
    except ValueError:
        return -1, None

def parse_quantity(lines, pos):
    line = lines[pos]
    if line[0] in '0123456789':
        # line starts with a number
        return pos + 1, line
    raise ValueError("Line %r doesn't contain a quantity" % line)

def parse_ingredientname(lines, pos):
    line = lines[pos]
    if line:
        # any non-empty line is ok as an ingredient name
        return pos + 1, line
    raise ValueError("Expected an ingredient name, found blank line, lineno=%d" % pos)

这称为递归下降解析。

在这个例子中,每个函数都接受一个pos应该开始查找的行号,并返回“下一个”行来查看 + 它找到的值。

我使用了两种不同的方法来指示解析错误:-1作为位置(和None值)返回,或者引发异常。任何一个都可能有用。

于 2012-08-11T10:14:25.817 回答
1

您会注意到几件事...
1. 我删除了您在循环之前列出的许多变量。你真的不需要在循环之前列出它们。
2.我把它切换到一个while循环。我个人喜欢能够一次读一行的吸引力
3. 我在名称部分写了类别,这只是因为当新食谱开始时该类别并不总是列出,所以我认为它会最好使用最后一个已知类别并将其插入每个新食谱的前面。
4. 你的份量并不总是列出来,所以我冒昧地在那里添加了一个检查,所以它会返回“未列出的份量”以防万一。
5. 我在配料上使用了一个循环。

注意:
1. 由于and line每个if step == 1 and line:. 该变量line被剥离所有行返回,因此 while 循环跳过所有新行。这些步骤只是确保我们在跳过每个空白行后做正确的事情。
2. 坚果面包听起来很好吃

代码:

category=''
step=0

menu = open("menuTextFormat.txt", 'r')
xml = open('menuTextXML.txt', 'w')

xml.write("<recipe>\n")

while 1:
    line = menu.readline()
    if not line:
        break

    #after checking for EOF, remove \n
    line = line.rstrip()

    #category
    if ":" in line:
        #set category as next line
        category = menu.readline().rstrip()
        step=1
        continue

    #name & servings
    if step == 1 and line:
        #write category
        xml.write("\t<category>\n\t\t" + category + "\n\t</category>\n")
        #write name
        xml.write("\t<name>\n\t\t" + line + "\n\t</name>\n")

        #check for serving size
        servings = menu.readline().rstrip()
        if not servings:
            xml.write("\t<servings>\n\t\tno serving size listed\n\t</servings>\n")
        else:
            xml.write("\t<servings>\n\t\t" + servings + "\n\t</servings>\n")

        step=2
        continue

    #ingredients
    if step == 2 and line:
        #write first ingredient, then loop for rest
        xml.write("\t<qty>\n\t\t" + line + "\n\t</qty>\n")
        xml.write("\t<ingredient>\n\t\t" + menu.readline().rstrip() + "\n\t</ingredient>\n")

        #loop for incredients
        while 1:
            qty = menu.readline().rstrip()
            #no more incredients, break loop
            if not qty:
                break

            xml.write("\t<qty>\n\t\t" + qty + "\n\t</qty>\n")
            xml.write("\t<ingredient>\n\t\t" + menu.readline().rstrip() + "\n\t</ingredient>\n")

        step=3
        continue

    #procedure
    if step == 3 and line:
        #write first step, then loop for rest
        xml.write("\t<procedure>\n")
        xml.write("\t\t<step>\n\t\t\t" + line + "\n\t\t</step>\n")

        #loop for steps
        while 1:
            step = menu.readline().rstrip()
            #no more steps, break loop
            if not step:
                break

            xml.write("\t\t<step>\n\t\t\t" + step + "\n\t\t</step>\n")

        xml.write("\t</procedure>\n")

        step=1
        continue

xml.write("</recipe>")
menu.close()
xml.close()

输出:

<recipe>
    <category>
        Breakfast Breads
    </category>
    <name>
        Gluten Free Nut Loaf
    </name>
    <servings>
        Makes 1 loaf
    </servings>
    <qty>
        150 g (51/2 oz./11/2 cups)
    </qty>
    <ingredient>
        almond meal
    </ingredient>
    <qty>
        30 g (1 oz./1/4 cup)
    </qty>
    <ingredient>
        walnuts, coarsely chopped
    </ingredient>
    <qty>
        1/4 teaspoon
    </qty>
    <ingredient>
        gluten-free baking powder
    </ingredient>
    <qty>
        1 teaspoon
    </qty>
    <ingredient>
        ground cinnamon
    </ingredient>
    <qty>
        95 g (31/4 oz./3/4 cup)
    </qty>
    <ingredient>
        arrowroot (tapioca) flour
    </ingredient>
    <qty>
        1/2 teaspoon
    </qty>
    <ingredient>
        sea salt
    </ingredient>
    <qty>
        3
    </qty>
    <ingredient>
        organic eggs
    </ingredient>
    <qty>
        1/2 teaspoon
    </qty>
    <ingredient>
        stevia powder
    </ingredient>
    <qty>
        3 tablespoons
    </qty>
    <ingredient>
        grape seed oil
    </ingredient>
    <qty>
        2 tablespoons
    </qty>
    <ingredient>
        coconut Milk
    </ingredient>
    <qty>
        1 teaspoon
    </qty>
    <ingredient>
        apple cider vinegar
    </ingredient>
    <procedure>
        <step>
            Preheat the oven to 180∫C (350∫F/Gas 4).
        </step>
        <step>
            Grease a 20 x 9 cm (8 x 31/2 inch) loaf (bar) tin.
        </step>
        <step>
            Put the almond meal, walnuts, baking powder, cinnamon, arrowroot flour and salt in a large bowl and mix well with a wooden spoon.
        </step>
        <step>
            Crack the eggs into a separate bowl and whisk using an electric mixer until pale and fluffy, about 11/2 minutes.
        </step>
        <step>
            Add the stevia, grape seed oil, coconut milk and vinegar and mix gently.
        </step>
        <step>
            Pour the mixture into the dry ingredients and stir to combine.
        </step>
        <step>
            Spoon the mixture into the greased tin and bake for about 40 minutes, or until a skewer inserted in the centre of the loaf comes out clean.
        </step>
        <step>
            Remove the bread from the oven and leave to cool in the tin for a few minutes, before turning out onto a wire rack to cool completely.
        </step>
        <step>
            Enjoy the bread melt-in-the-mouth warm, or at room temperature with your favourite topping.
        </step>
    </procedure>
    <category>
        Breakfast Breads
    </category>
    <name>
        Basic Gluten Free Loaf
    </name>
    <servings>
        no serving size listed
    </servings>
    <qty>
        2Ω cups
    </qty>
    <ingredient>
        blanched almond flour
    </ingredient>
    <qty>
        Ω teaspoon
    </qty>
    <ingredient>
        baking soda
    </ingredient>
    <qty>
        1 tsp.
    </qty>
    <ingredient>
        bicarbonate of soda
    </ingredient>
    <qty>
        3
    </qty>
    <ingredient>
        eggs beaten
    </ingredient>
    <qty>
        1 tsp.
    </qty>
    <ingredient>
        stevia powder
    </ingredient>
    <qty>
        Ω teaspoon
    </qty>
    <ingredient>
        apple cider vinegar
    </ingredient>
    <qty>
        !!
    </qty>
    <ingredient>
        Pinch sea salt
    </ingredient>
    <procedure>
        <step>
            Preheat oven to 250 degrees Celsius
        </step>
        <step>
            Grease a small loaf pan
        </step>
        <step>
            Combine dry ingredients in a bowl
        </step>
        <step>
            In a separate bowl place eggs and apple cider vinegar
        </step>
        <step>
            Spoon the mixture into loaf pan
        </step>
        <step>
            Bake for 50 mins until set
        </step>
        <step>
            Cool on wire rack
        </step>
        <step>
            Slice when cool
        </step>
    </procedure>
</recipe>
于 2012-08-11T10:47:34.767 回答