gpt4 book ai didi

xml - 从自定义 xml 中提取字段

转载 作者:太空宇宙 更新时间:2023-11-04 12:16:50 25 4
gpt4 key购买 nike

我正在制作一个脚本来从 XML 中提取字段,现在我得到了这个,我需要让它工作,我正在尝试使用 2 for 和 greps,我需要一些帮助

#! /bin/bash

function charge_files () {
XML="Prueba.xml";
if [ -f "$XML" ]; then
echo "=============================";
echo "| XML CHARGED |";
echo "=============================";
else
echo "=============================";
echo "| XML NOT CHARGED |";
echo "=============================";
fi
}

function extract () {
#extract all from the file (not curr working)
x=`grep "Host"`
for $x in "$XML"
do
for LINEA in `cat $XML | grep "<Telegram" ` #LINEA guarda el resultado del fichero datos.txt
do
TIMESTAMP=`echo $LINEA | grep [Timestamp="*"] ` #Extracts TIMESTAMP
FRAMEFORMAT=`echo $LINEA | grep [FrameFormat="*"]` #Extracts FRAMEFORMAT
RAWDATA=`echo $LINEA | grep [RawData="*"]` #Extracts RAWDATA

echo "$x $HOST $TIMESTAMP $FRAMEFORMAT $RAWDATA" >> output.logs #Shows result
done
done
}

charge_files
extract

我得到了这个带有这些字段的 xml

 <CommunicationLog xmlns="http://knx.org/xml/telegrams/01">
<RecordStart Timestamp="" Mode="" Host="PC1" ConnectionName="" ConnectionOptions="" ConnectorType="" MediumType="" />
<Telegram Timestamp="" Service="" FrameFormat="" RawData="" />
<Telegram Timestamp="" Service="" FrameFormat="" RawData="" />

<RecordStart Timestamp="" Mode="" Host="PC2" ConnectionName="" ConnectionOptions="" ConnectorType="" MediumType="" />
<Telegram Timestamp="" Service="" FrameFormat="" RawData="" />
<Telegram Timestamp="" Service="" FrameFormat="" RawData="" />
<RecordStop Timestamp="" />
</CommunicationLog>

我想要这样的输出以进行更多比较:

HOST="PC1" ConnectorType="" Timestamp="" FrameFormat="" RawData=""
HOST="PC1" ConnectorType="" Timestamp="" FrameFormat="" RawData=""

HOST="PC2" ConnectorType="" Timestamp="" FrameFormat="" RawData=""
HOST="PC2" ConnectorType="" Timestamp="" FrameFormat="" RawData=""

最佳答案

代码有很多问题。

  • 一般:
    • 缩进您的代码,它使您和其他人更容易调试和支持代码。
    • 编写脚本时,几乎一行一行地编写,并测试每一行。添加变量的回显,...
    • 不要写一大堆行然后试图找出它不起作用的原因。
    • 例如。 extract() 中的第一行不起作用。如果您只用那一行尝试 extract(),请不要继续,先调试它。
  • Prueba.xml:
    • 您有一个 RecordStart,然后是另一个 RecordStart,而不是 RecordStop。您是否忘记了第一个 RecordStart 的 RecordStop?
    • 我添加了测试数据,因为很难用空字段进行调试。
  • 收费文件:
    • 除了检查文件是否存在之外什么都不做。不过还好。
    • 不需要';'在 echo 命令或 XML 赋值上。已删除。
    • 如果 XML 文件不存在,您的脚本将无论如何运行。我添加了一个导出,因为脚本的其余部分需要存在该文件。
  • 摘录:

    • 您不能像您尝试的那样使用 for 迭代行。因为将迭代每个单词。像我在代码中那样使用 while。
    • 你需要在每一行上循环,看看我的代码。您使用 grep Telegram 的方法不会区分 PC1 的 Telegram 线路和 PC2 的 Telegram 线路。
    • grep 命令返回整行。因此,如果您对一行中的某个词进行 grep,它不会返回该行的一部分,而是返回整行。
    • 要提取一行的部分内容,您可以使用 cut(就像我所做的那样,因为您的要求很简单)、awk、sed。
  • 假设:

    • 这些行总是以相同的顺序包含相同的信息。

下面是我用于测试的 XML 文件:

 <CommunicationLog xmlns="http://knx.org/xml/telegrams/01">
<RecordStart Timestamp="" Mode="" Host="PC1" ConnectionName="name1" ConnectionOptions="option1" ConnectorType="type1" MediumType="med1" />
<Telegram Timestamp="t1a" Service="s1a" FrameFormat="ff1a" RawData="rd1a" />
<Telegram Timestamp="t1b" Service="s1b" FrameFormat="ff1b" RawData="rd1b" />

<RecordStart Timestamp="" Mode="" Host="PC2" ConnectionName="name2" ConnectionOptions="option2" ConnectorType="type2" MediumType="med2" />
<Telegram Timestamp="t2a" Service="s2a" FrameFormat="ff2a" RawData="rd2a" />
<Telegram Timestamp="t2b" Service="s2b" FrameFormat="ff2b" RawData="rd2b" />
<RecordStop Timestamp="stoptimestamp" />
</CommunicationLog>

这里是脚本:

#! /bin/bash

function charge_files ()
{
XML="Prueba.xml"
if [ -f "$XML" ]; then
echo "============================="
echo "| XML CHARGED |"
echo "============================="
else
echo "============================="
echo "| XML NOT CHARGED |"
echo "============================="
exit 1
fi
}

function extract ()
{
host=''

while IFS= read -r line; do
# Find if it is a RecordtStart line
if [ $(echo $line | grep -c "RecordStart") -eq 1 ]
then
# If host == '', then it is the first host we see.
# Otherwise, we are changing host, so print an empty line
if [ "$host" != '' ]
then
echo ""
fi

# Collect the host information
host=$(echo $line | awk '{print $4}' | cut -d'"' -f2)

# Collect the ConnectorType information
connectortype=$(echo $line | awk '{print $7}')

# Done with this loop in the while, move on to the next
continue
fi

# Find if it is a Telegram line
if [ $(echo $line | grep -c "Telegram") -eq 1 ]
then
# Collect the Timestamp information
timestamp=$(echo $line | awk '{print $2}')

# Collect the FrameFormat information
frameformat=$(echo $line | awk '{print $4}')

# Collect the RawData information
rawdata=$(echo $line | awk '{print $5}')

# Print the information
echo "HOST=\"$host\" $connectortype $timestamp $frameformat $rawdata"

# Done with this loop in the while, move on to the next
continue
fi

done <$XML
}

charge_files
extract

产生了这个输出:

=============================
| XML CHARGED |
=============================
HOST="PC1" ConnectorType="type1" Timestamp="t1a" FrameFormat="ff1a" RawData="rd1a"
HOST="PC1" ConnectorType="type1" Timestamp="t1b" FrameFormat="ff1b" RawData="rd1b"

HOST="PC2" ConnectorType="type2" Timestamp="t2a" FrameFormat="ff2a" RawData="rd2a"
HOST="PC2" ConnectorType="type2" Timestamp="t2b" FrameFormat="ff2b" RawData="rd2b"

关于xml - 从自定义 xml 中提取字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47200564/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com